poj 2778
自动机+矩阵乘。
代码:
#include<iostream> #include<fstream> using namespace std; struct e{ int p[5]; int end; }trie[101]; int m,K,n; int hash[128]; int state=1; long long s; int f[101]; void build(char c[]){ int i,j=0,k; for(i=1;;) { if(trie[i].p[hash[c[j]]]==0) trie[i].p[hash[c[j]]]=++state; i=trie[i].p[hash[c[j]]]; j++; if(j>=strlen(c)) break; } trie[i].end=1; } void ac(){ int q[111]; int l=0,r=0; int i,j,k; for(i=0;i<n;i++) if(trie[1].p[i]) { q[++r]=trie[1].p[i]; f[trie[1].p[i]]=1; } else { trie[1].p[i]=1; } while(l<r){ i=q[++l]; for(j=0;j<n;j++) { if(trie[i].p[j]) { q[++r]=trie[i].p[j]; k=f[i]; while(!trie[k].p[j]) k=f[k]; f[trie[i].p[j]]=trie[k].p[j]; trie[trie[i].p[j]].end|=trie[trie[k].p[j]].end; } } } } long long map[101][101],map1[101][101],map2[101][101]; void solve(long long s){ int i,j,k; if(s==1) for(i=1;i<=state;i++) for(j=1;j<=state;j++) map1[i][j]=map[i][j]; else { solve(s/2); for(i=1;i<=state;i++) for(j=1;j<=state;j++) for(k=1,map2[i][j]=0;k<=state;k++) { map2[i][j]+=map1[i][k]*map1[k][j]; map2[i][j]%=100000; } if(s/2*2==s) { for(i=1;i<=state;i++) for(j=1;j<=state;j++) map1[i][j]=map2[i][j]; } else { for(i=1;i<=state;i++) for(j=1;j<=state;j++) for(k=1,map1[i][j]=0;k<=state;k++) { map1[i][j]+=map2[i][k]*map[k][j]; map1[i][j]%=100000; } } } } void loop(){ int i,j,k; for(i=1;i<=state;i++) if(trie[i].end) continue; else { for(j=0;j<n;j++) if(trie[i].p[j]) { k=trie[i].p[j]; if(trie[k].end==0) map[i][k]++; } else { k=f[i]; while(!trie[k].p[j]) k=f[k]; if(!trie[trie[k].p[j]].end) { k=trie[k].p[j]; map[i][k]++; } } } } void read(){ // ifstream cin("in.txt"); int i,j,k; char c[20]; cin>>m>>s; hash['A']=0; hash['C']=1; hash['T']=2; hash['G']=3; n=4; for(i=1;i<=m;i++) { cin>>c; build(c); } ac(); loop(); solve(s); long long ans=0; for(i=1;i<=state;i++) { ans+=map1[1][i]; ans%=100000; } cout<<ans<<endl; } int main(){ read(); return 0; }