一眼题。。。。。
论文里讲了一大堆其实就是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;
}