bzoj 1009 GT考试
还是套路题,和bzoj1030基本一样
就是多了矩乘优化
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; int n,m,tot,ans,mod; char s[105]; bool ed[6005]; struct Tree{ int son[10]; int fail; }tr[6005]; struct node{ int f[27][27]; }squ,ret; void build(char b[]){ int now=0,len=strlen(b+1); for(int i=1;i<=len;i++){ int k=b[i]-'0'; if(!tr[now].son[k])tr[now].son[k]=++tot; now=tr[now].son[k]; } ed[now]=true; } void getfail(){ queue<int>que; for(int i=0;i<10;i++){ if(tr[0].son[i]){ que.push(tr[0].son[i]); } } while(!que.empty()){ int u=que.front(); que.pop(); for(int i=0;i<10;i++){ if(!tr[u].son[i]){ tr[u].son[i]=tr[tr[u].fail].son[i]; continue; } tr[tr[u].son[i]].fail=tr[tr[u].fail].son[i]; que.push(tr[u].son[i]); } } } node mul(node &a,node &b){ node c; memset(c.f,0,sizeof(c.f)); for(int i=0;i<=tot;i++){ for(int j=0;j<=tot;j++){ for(int k=0;k<=tot;k++){ c.f[i][j]+=(a.f[i][k]*b.f[k][j])%mod; c.f[i][j]%=mod; } } } return c; } void fast_pow(int x){ while(x){ if(x%2){ ret=mul(ret,squ); } x/=2; squ=mul(squ,squ); } } void DP(){ for(int i=0;i<=tot;i++){ if(ed[i])continue; for(int j=0;j<=9;j++){ if(!ed[tr[i].son[j]])squ.f[i][tr[i].son[j]]+=1; } } } int main(){ scanf("%d%d%d",&n,&m,&mod); scanf("%s",s+1);build(s); getfail();DP(); ret=squ; fast_pow(n-1); for(int i=0;i<=tot;i++){ if(!ed[i]){ (ans+=ret.f[0][i])%=mod; } } printf("%d\n",ans); return 0; }