1 条题解
-
0
自动搬运
来自洛谷,原作者为

Fading
AFO搬运于
2025-08-24 22:09:43,当前版本为作者最后更新于2019-05-04 20:35:31,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
有点思维含量的题啊。
虽然作为省选题太套路了。
很显然是
设表示长度为,末位为字符的方案数
很显然的转移式
但是很大,怎么办呢?
发现是否可以转移的情况是固定的
可以考虑使用矩阵来判断是否可以转移。
如果字符串不为的子串,那么矩阵中,否则。
大小为。
一次转移就是做一次矩阵乘法
$\begin{bmatrix}f[1] & f[2] & ... &f[26]\end{bmatrix}\times X$
为什么呢?
因为
也就是
就是
正好是矩阵的形式。
由于初始条件下,所以我们只要求出矩阵中所有数的和就好了。矩阵快速幂做到时间复杂度
// luogu-judger-enable-o2 #include<bits/stdc++.h> #define ljc 1000000007 using namespace std; long long n,m,pr,nf,x; char s[1000001]; struct matrix{ long long x[27][27];long long sz; inline void clear(){ for (int i=1;i<=26;i++){ for (int j=1;j<=26;j++){ x[i][j]=0; } } } }a,one; inline matrix mul(matrix a,matrix b){ matrix c; c.clear();c.sz=a.sz; for (int i=1;i<=26;i++){ for (int j=1;j<=26;j++){ for (int k=1;k<=26;k++){ c.x[i][j]=(c.x[i][j]%ljc+a.x[i][k]%ljc*b.x[k][j]%ljc)%ljc; } } } return c; } inline matrix fast_pow(matrix a,long long b){ matrix t=one; while (b){ if (b&1LL) t=mul(t,a); a=mul(a,a);b/=2LL; } return t; } inline void init_one(){ one.sz=a.sz; for (int i=1;i<=26;i++){ one.x[i][i]=1; } } int main(){ scanf("%lld",&n); init_one(); for (int i=1;i<=26;i++){ for (int j=1;j<=26;j++){ a.x[i][j]=1; } } scanf("%s",s+1); int len=strlen(s+1); for (int i=2;i<=len;i++){ a.x[s[i-1]-'a'+1][s[i]-'a'+1]=0; } a=fast_pow(a,n-1); long long ans=0; for (int i=1;i<=26;i++){ for (int j=1;j<=26;j++){ ans=(ans+a.x[i][j])%ljc; } } cout<<ans; }
- 1
信息
- ID
- 4328
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者