CF177G
模拟赛题,记录一下。
\(k\le 29\) 时直接 ACAM 即可(这一步实际上是最后得到的),下面考虑 \(k>29\) 的情况。
记 \(F_{i,j}\) 表示 \(s_j\) 在 \(f_i\) 中的出现次数。
设 \(F_{i,j}=F_{i-1,j}+F_{i-2,j}+k_{i,j}\),则 \(k_{i,j}\) 是 \(f_{i-1}\) 的一个后缀拼上 \(f_{i-2}\) 的一个前缀得到 \(s_j\) 的次数。
于是只需要关心 \(f_i\) 的最前和最后的 \(100000\) 个字符。
容易计算得到 \(fib_{26}\ge100000\),不难发现 \(i\ge26\) 时 \(f_i\) 的最前 \(100000\) 个字符保持不变,\(i\ge28\) 时 \(f_i\) 的最后 \(100000\) 个字符与 \(f_{i-2}\) 相同。
于是可得 \(i\ge28\) 时 \(k_{i,j}=k_{i-2,j}\),那么矩阵快速幂即可,关键在于求 \(F_{26,j},F_{27,j},k_{28,j},k_{29,j}\),使用 ACAM 求出 \(F_{26,j},F_{27,j},F_{28,j},F_{29,j}\) 即可。
时间复杂度 \(O(\sum\lvert s\rvert+q\log n)\),但是建自动机的时候不优化也能过?
#include<bits/stdc++.h>
using namespace std;
namespace ax_by_c{
typedef long long ll;
const int mod=1e9+7;
const int QQ=1e5+5;
const int M=35;
const int L=514229+5;
const int LS=1e5+5;
char str[M][L];
int len[M];
void Init(){
len[1]=1;
str[1][1]='a';
len[2]=1;
str[2][1]='b';
for(int i=3;i<=29;i++){
len[i]=len[i-1]+len[i-2];
for(int j=1;j<=len[i-1];j++){
str[i][j]=str[i-1][j];
}
for(int j=1;j<=len[i-2];j++){
str[i][len[i-1]+j]=str[i-2][j];
}
}
}
ll n;
int q,pos[QQ];
char s[LS];
int idx,son[LS][2];
int ins(){
int u=0;
for(int i=1;s[i];i++){
if(!son[u][s[i]-'a'])son[u][s[i]-'a']=++idx;
u=son[u][s[i]-'a'];
}
return u;
}
queue<int>Q;
int nxt[LS],lst[LS],id;
void bld_acam(){
Q.push(0);
while(Q.size()){
int u=Q.front();
Q.pop();
lst[++id]=u;
for(int i=0;i<=1;i++){
if(!u){
if(son[u][i])Q.push(son[u][i]);
continue;
}
if(son[u][i]){
nxt[son[u][i]]=son[nxt[u]][i];
Q.push(son[u][i]);
}
else son[u][i]=son[nxt[u]][i];
}
}
}
int cnt[LS],f26[QQ],f27[QQ],f28[QQ],f29[QQ];
void mch(int n){
for(int i=0;i<=idx;i++)cnt[i]=0;
int u=0;
for(int i=1;i<=len[n];i++){
u=son[u][str[n][i]-'a'];
cnt[u]++;
}
for(int i=idx+1;i>=1;i--)cnt[nxt[lst[i]]]+=cnt[lst[i]];
}
struct matr{
int n,m;
int a[3][3];
void clr(){
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
a[i][j]=0;
}
};
matr operator * (const matr& a,const matr& b){
matr c;
c.n=a.n;
c.m=b.m;
c.clr();
for(int i=0;i<a.n;i++){
for(int j=0;j<a.m;j++){
for(int k=0;k<b.m;k++){
c.a[i][k]=(c.a[i][k]+(ll)a.a[i][j]*b.a[j][k]%mod)%mod;
}
}
}
return c;
}
matr operator ^ (matr a,ll b){
matr r=a;
b--;
while(b){
if(b&1){
r=r*a;
}
a=a*a;
b>>=1;
}
return r;
}
void main(){
Init();
scanf("%lld %d",&n,&q);
for(int i=1;i<=q;i++){
scanf("%s",s+1);
pos[i]=ins();
}
bld_acam();
if(n<=29){
mch(n);
for(int i=1;i<=q;i++){
printf("%d\n",cnt[pos[i]]);
}
}
else{
mch(26);
for(int i=1;i<=q;i++)f26[i]=cnt[pos[i]];
mch(27);
for(int i=1;i<=q;i++)f27[i]=cnt[pos[i]];
mch(28);
for(int i=1;i<=q;i++)f28[i]=cnt[pos[i]];
mch(29);
for(int i=1;i<=q;i++)f29[i]=cnt[pos[i]];
matr g0,g1,S,gg;
g0.n=3;
g0.m=3;
g0.clr();
g0.a[1][0]=1;
g0.a[0][1]=1;
g0.a[1][1]=1;
g0.a[2][2]=1;
g1.n=3;
g1.m=3;
g1.clr();
g1.a[1][0]=1;
g1.a[0][1]=1;
g1.a[1][1]=1;
g1.a[2][2]=1;
S.n=1;
S.m=3;
for(int i=1;i<=q;i++){
g0.a[2][1]=((ll)f28[i]-f27[i]-f26[i]+mod*2)%mod;
g1.a[2][1]=((ll)f29[i]-f28[i]-f27[i]+mod*2)%mod;
S.a[0][0]=f28[i];
S.a[0][1]=f29[i];
S.a[0][2]=1;
gg=g0*g1;
gg=gg^((n-29)/2);
S=S*gg;
if(n%2==0)S=S*g0;
printf("%d\n",S.a[0][1]);
}
}
}
}
int main(){
ax_by_c::main();
return 0;
}

浙公网安备 33010602011771号