@Jerusalem
2015-11-12T00:50:06.000000Z
字数 2691
阅读 1682
很容易想到,本题是一道AC自动机上的DP。
定义状态函数
那么显然,答案等于
考虑状态函数的转移,引入辅助函数
容易发现,
这式子可以看作两个矩阵间的乘法,而
边界条件是,
#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <algorithm>#include <iostream>#include <queue>typedef long long ll;using namespace std;const int maxnode=15*15,sigma=4;const int MOD=100000;queue<int> Q;struct Trie{int tot;int ch[maxnode][sigma];int f[maxnode];bool danger[maxnode];Trie(){tot=1;memset(ch,0,sizeof(ch));memset(f,0,sizeof(f));memset(danger,false,sizeof(danger));}inline int idx(char a){if(a=='A')return 0;if(a=='C')return 1;if(a=='G')return 2;return 3;}void Clear(){tot=1;memset(ch[0],0,sizeof(ch[0]));memset(danger,false,sizeof(danger));}int newnode(){memset(ch[tot],0,sizeof(ch[tot]));return tot++;}void Insert(string s){int len=s.length();int u=0;for(int i=0;i<len;i++){if(ch[u][idx(s[i])]==0)ch[u][idx(s[i])]=newnode();u=ch[u][idx(s[i])];}danger[u]=true;}void Build(){while(!Q.empty())Q.pop();for(int i=0;i<sigma;i++){if(ch[0][i]){f[ch[0][i]]=0;Q.push(ch[0][i]);}}while(!Q.empty()){int u=Q.front();Q.pop();for(int i=0;i<sigma;i++){if(ch[u][i]==0){ch[u][i]=ch[f[u]][i];continue;}int v=ch[u][i];Q.push(v);int r=f[u];while(r&&ch[r][i]==0)r=f[r];f[v]=ch[r][i];danger[v]|=danger[f[v]];}}}};struct Matrix{int l,r;ll a[maxnode][maxnode];Matrix(){l=r=0;memset(a,0,sizeof(a));}Matrix operator *(const Matrix& o)const{Matrix c;for(int i=0;i<=l;i++)for(int j=0;j<=o.r;j++)for(int k=0;k<=r;k++){c.a[i][j]+=(a[i][k]*o.a[k][j]);c.a[i][j]%=MOD;}c.l=l;c.r=o.r;return c;}void Print(){for(int i=0;i<=l;i++){for(int j=0;j<=r;j++)cout<<a[i][j]<<" ";printf("\n");}}};Trie Aho_Corasick;Matrix Base;Matrix E;Matrix From;int n;int m;string S;void First(){Aho_Corasick.Build();Base.l=Base.r=Aho_Corasick.tot-1;E.l=E.r=Base.l;From.l=0;From.r=Base.r;for(int i=0;i<=E.l;i++)E.a[i][i]=1;for(int i=0;i<=Base.l;i++)if(!Aho_Corasick.danger[i])for(int j=0;j<=Base.r;j++)if(!Aho_Corasick.danger[j])for(int k=0;k<sigma;k++)if(Aho_Corasick.ch[i][k]==j)Base.a[i][j]++;for(int j=0;j<sigma;j++)From.a[0][Aho_Corasick.ch[0][j]]++;}Matrix Power(Matrix O,int a){Matrix ans=E;while(a>0){if(a&1)ans=ans*O;O=O*O;a>>=1;}return ans;}void Solve(){From=From*Power(Base,n-1);ll ans=0;for(int i=0;i<=From.r;i++)if(!Aho_Corasick.danger[i])ans+=From.a[0][i];cout<<ans%MOD;}void ReadData(){freopen("POJ2778.in","r",stdin);scanf("%d%d",&m,&n);for(int i=1;i<=m;i++){cin>>S;Aho_Corasick.Insert(S);}}void Close(){fclose(stdin);fclose(stdout);}int main(){ReadData();First();Solve();Close();return 0;}