[HNOI2008]GT考试
Code:
#include<cstdio> #include<algorithm> #include<string> #include<cstring> #include<queue> #define ll long long using namespace std; void setIO(string a){ freopen((a+".in").c_str(),"r",stdin);} int nodes,mod; char arr[30]; struct matrix{ int mat[105][105]; }unit; void init(matrix &a){ for(int i=0;i<=nodes;++i) for(int j=0;j<=nodes;++j) a.mat[i][j]=0; } void get(matrix &a){ init(a); for(int i=0;i<=nodes;++i) a.mat[i][i]=1; } matrix operator*(matrix a,matrix b){ matrix c; init(c); for(int i=0;i<=nodes;++i) for(int j=0;j<=nodes;++j) for(int k=0;k<=nodes;++k) c.mat[i][j]=((ll)(a.mat[i][k]*b.mat[k][j])%mod+c.mat[i][j])%mod; return c; } matrix operator^(matrix a,int p){ matrix ans; get(ans); while(p){ if(p&1)ans=ans*a; a=a*a; p>>=1; } return ans; } struct Automaton{ #define idx str[i]-'0' #define maxn 30000 #define sigma 10 int ch[maxn][sigma], fail[maxn]; bool tag[maxn]; void insert(char str[]){ int n=strlen(str),j=0; for(int i=0;i<n;++i){ if(!ch[j][idx]) ch[j][idx]=++nodes; j=ch[j][idx]; } tag[j]=true; } queue<int>Q; void build(){ for(int i=0;i<sigma;++i) if(ch[0][i]) Q.push(ch[0][i]); while(!Q.empty()){ int u=Q.front();Q.pop(); for(int i=0;i<sigma;++i){ int r=ch[u][i]; if(!r) { ch[u][i]=ch[fail[u]][i]; continue;} Q.push(r); fail[r]=ch[fail[u]][i]; if(tag[fail[r]]) tag[r]=true; } } init(unit); for(int i=0;i<=nodes;++i) for(int j=0;j<sigma;++j) if(!tag[i]&&!tag[ch[i][j]]) unit.mat[i][ch[i][j]]+=1; } }aho; int main(){ //setIO("input"); int n,m; scanf("%d%d%d",&n,&m,&mod); scanf("%s",arr); aho.insert(arr), aho.build(); matrix final=unit^n; int ans=0; for(int i=0;i<=nodes;++i) ans+=final.mat[0][i], ans%=mod; printf("%d",ans); return 0; }