1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 char ch[105],s[106]; 6 int n,m,a[6007][27],size=1,fail[6007],dui[6007],b[101][6007],sum,sum1; 7 bool f[6007]; 8 void jia() 9 { 10 int now=1,l=strlen(ch); 11 for(int i=0;i<l;i++) 12 { 13 int t=ch[i]-'A'+1; 14 if(a[now][t]) 15 now=a[now][t]; 16 else 17 { 18 size++; 19 now=a[now][t]=size; 20 } 21 } 22 f[now]=1; 23 } 24 void shi() 25 { 26 int t=1,h=0; 27 dui[1]=1; 28 for(;h<t;) 29 { 30 int k=dui[++h]; 31 for(int i=1;i<=26;i++) 32 if(a[k][i]) 33 { 34 int x=fail[k]; 35 for(;!a[x][i];x=fail[x]); 36 fail[a[k][i]]=a[x][i]; 37 if(f[a[x][i]]) 38 f[a[k][i]]=1; 39 dui[++t]=a[k][i]; 40 } 41 } 42 } 43 void dp(int a1) 44 { 45 for(int i=1;i<=size;i++) 46 { 47 if(f[i]||!b[a1-1][i]) 48 continue; 49 for(int j=1;j<=26;j++) 50 { 51 int k=i; 52 for(;!a[k][j];k=fail[k]); 53 b[a1][a[k][j]]=(b[a1][a[k][j]]+b[a1-1][i])%10007; 54 } 55 } 56 } 57 int main() 58 { 59 for(int i=1;i<=26;i++) 60 a[0][i]=1; 61 scanf("%d%d",&n,&m); 62 for(int i=0;i<n;i++) 63 { 64 scanf("%s",ch); 65 jia(); 66 } 67 shi(); 68 b[0][1]=1; 69 for(int i=1;i<=m;i++) 70 dp(i); 71 sum=1; 72 for(int i=1;i<=m;i++) 73 sum=(sum*26)%10007; 74 for(int i=1;i<=size;i++) 75 if(!f[i]) 76 sum1=(sum1+b[m][i])%10007; 77 printf("%d\n",(sum-sum1+10007)%10007); 78 return 0; 79 }
AC自动机 将所有单词读入建出AC自动机,再在fail树上跑即可,用总可能数减去没有单词的数,没有单词的数用dp求,b[i][j]是第i个字符匹配到AC自动机上的j节点