一眼题。。。。。
论文里讲了一大堆其实就是ac自动机上乱搞嘛。
然后就是论如何把一道水题出成神题,技巧就是……卡常数。。。。。。。
首先会发现某些情况下trie树的很多节点都到不了(比如说根节点的A子节点是叶子,于是所有串只要到A全都cut了)
所以存在大量的无用状态,全部剪掉就能过了。
话说现在才发现原来ac自动机的fail指针和kmp的fail一样可以通过一个循环遍历所有的(既是前缀又是后缀的逗比)
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; typedef long long ll; const int N=60+5; const int p=(1e4)+7; int m; struct matrix{ ll a[N][N]; matrix(){ memset(a,0,sizeof(a)); } void clear(){ memset(a,0,sizeof(a)); } void print(){ for(int i=0;i<=m;i++){ for(int j=0;j<=m;j++) printf("%d ",a[i][j]); putchar('\n'); } } matrix operator * (const matrix &b)const{ static matrix ans; ans.clear(); for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) for(int k=0;k<=m;k++) ans.a[i][j]+=a[i][k]*b.a[k][j]; for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) ans.a[i][j]%=p; return ans; } matrix operator ^ (int k)const{ static matrix ans,b; ans.clear(); memcpy(b.a,a,sizeof(a)); for(int i=0;i<=m;i++)ans.a[i][i]=1; for(;k;k>>=1,b=b*b)if(k&1)ans=ans*b; return ans; } }; ll g[N][N]; struct Node{ int fail,ch[26],val; void clear(){ fail=val=0; memset(ch,0,sizeof(ch)); } }tr[N]; void ins(char *s){ int u; for(u=0;*s;s++){ int c=(*s)-'A'; if(!tr[u].ch[c]){ tr[u].ch[c]=++m; tr[m].clear(); } u=tr[u].ch[c]; } tr[u].val++; } void bfs(){ queue<int>q;q.push(0); while(!q.empty()){ int u=q.front();q.pop(); for(int i=0;i<26;i++) if(tr[u].ch[i]){ int v=tr[u].ch[i]; if(u)tr[v].fail=tr[tr[u].fail].ch[i]; q.push(v); }else tr[u].ch[i]=tr[tr[u].fail].ch[i]; } } int idx[N]; void bfs2(){ queue<int>q;q.push(0); int sz=0; memset(idx,0,sizeof(idx)); while(!q.empty()){ int u=q.front();q.pop(); for(int i=0;i<26;i++){ int v=tr[u].ch[i]; bool flag=true; for(int p=v;p;p=tr[p].fail) if(tr[p].val){ flag=false; break; } if(!flag)continue; if(v&&!idx[v]){ idx[v]=++sz; q.push(v); } g[idx[u]][idx[v]]++; } } m=sz; } int qmul(int a,int b){ int ans=1; for(;b;b>>=1,a=a*a%p)if(b&1)ans=ans*a%p; return ans; } char s[15]; int main(){ //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); int n,l; while(~scanf("%d%d",&n,&l)){ m=0;tr[0].clear(); while(n--){ scanf("%s",s); ins(s); } memset(g,0,sizeof(g)); bfs(); bfs2(); static matrix A; memcpy(A.a,g,sizeof(g)); A=A^l; int ans=0; for(int i=0;i<=m;i++) ans=(ans+A.a[0][i])%p; ans=((qmul(26,l)-ans)%p+p)%p; printf("%d\n",ans); } return 0; }