题解:
AC自动机模板,蒟蒻太菜,把AC自动机忘的差不多了。
然后昨天一天恶补KMP,trie
终于搞完了。
由于直接求合法方案有点难搞,所以我们求不合法的,
f[i][j]表示第i个位置,匹配到j的方案数,
代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define mod 10007
const int N=6110;
int n,m,len;
char s[100];
bool tf[N];
struct node{
int fail,a[50];
}sa[N];int tot=1,root=1;
void build()
{
int len=strlen(s+1);
int x=root;
for(int i=1;i<=len;i++)
{
int c=s[i]-'A';
if(sa[x].a[c]) x=sa[x].a[c];
else x=sa[x].a[c]=++tot;
}
tf[x]=true;
}
queue<int> q;
void make_fail()
{
q.push(root);
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=0;i<26;i++)
{
if(!sa[x].a[i]) continue;
if(x==root) sa[sa[x].a[i]].fail=root;
else
{
int j=sa[x].fail;
while(j!=root&&!sa[j].a[i]) j=sa[j].fail;
sa[sa[x].a[i]].fail=sa[j].a[i];
if(tf[sa[j].a[i]]) tf[sa[x].a[i]]=true;
}
q.push(sa[x].a[i]);
}
}
}
int f[120][N];
void DP(int x)
{
for(int i=1;i<=tot;i++)
{
if(tf[i]||!f[x-1][i]) continue;
for(int j=0;j<26;j++)
{
int k=i;
while(!sa[k].a[j]) k=sa[k].fail;
f[x][sa[k].a[j]]=(f[x-1][i]+f[x][sa[k].a[j]])%mod;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
memset(tf,0,sizeof(tf));
for(int i=0;i<26;i++) sa[root].a[i]=++tot;
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
build();
}
make_fail();
memset(f,0,sizeof(f));
f[0][1]=1;
for(int i=1;i<=m;i++) DP(i);
int ans2=1,ans1=0;
for(int i=1;i<=m;i++)
ans2=(ans2*26)%mod;
for(int i=1;i<=tot;i++)
if(!tf[i]) ans1=(ans1+f[m][i])%mod;
printf("%d",((ans2-ans1)%mod+mod)%mod);
}