首先利用病毒串建立tire图,没个节点代表某种后缀,然后利用AC自动机对各个后缀进行转移,得到一个矩阵,然后利用快速幂求解矩阵连乘。
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
using namespace std;
const int nMax=105;
const int S_NUM=4;
const int N_NUM=105;
const int M=100000;
struct Tree
{
int index,flag;
Tree *fail,*next[S_NUM];
}t[nMax],*Q[nMax];
struct Mat
{
long long mat[N_NUM][N_NUM];
int n,m;
void init(int r,int c)
{
n=r;m=c;
}
void init_e()
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
mat[i][j]=(i==j);
}
};
int cnt,L,C;
long long a[N_NUM][N_NUM];
char key[20];
Tree *root;
int get(char c)
{
if(c=='A') return 0;
else if(c=='G') return 1;
else if(c=='C') return 2;
else return 3;
}
Tree* new_node()
{
Tree *p=&t[cnt];
p->index=cnt++;
p->flag=0;
memset(p->next,0,sizeof(p->next));
return p;
}
void insert(char s[])
{
Tree *p=root;
for(int i=0;s[i];i++)
{
int index=get(s[i]);
if(p->next[index]==NULL)
p->next[index]=new_node();
p=p->next[index];
}
p->flag=1;
}
void build_ac()
{
int f=0,r=-1;
Q[++r]=root;
while(f<=r)
{
Tree *p=Q[f++];
for(int i=0;i<S_NUM;i++)
{
if(p->next[i]!=NULL)
{
if(p==root) p->next[i]->fail=root;
else
{
p->next[i]->fail=p->fail->next[i];
if(p->fail->next[i]->flag!=0)
p->next[i]->flag=1;
}
Q[++r]=p->next[i];
}
else
{
if(p==root) p->next[i]=root;
else p->next[i]=p->fail->next[i];
}
if(p->next[i]->flag==0) a[p->index][p->next[i]->index]++;
}
}
}
Mat Mul(Mat a,Mat b)
{
Mat ret;
ret.init(a.n,b.m);
memset(ret.mat,0,sizeof(ret.mat));
for(int i=0;i<a.n;i++)
for(int j=0;j<b.m;j++)
for(int k=0;k<b.n;k++)
{
ret.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
if(ret.mat[i][j]>M) ret.mat[i][j]%=M;
}
return ret;
}
Mat exp(Mat a,int k)
{
Mat ret=a,tmp=a;
ret.init_e();
for(;k;k>>=1)
{
if(k&1)
{
ret=Mul(ret,tmp);
}
tmp=Mul(tmp,tmp);
}
return ret;
}
int main()
{
// freopen("test.txt","r",stdin);
scanf("%d%d",&L,&C);
cnt=0;root=new_node();
for(int i=0;i<L;i++)
{
scanf("%s",key);
insert(key);
}
build_ac();
Mat b; b.init(cnt,cnt);
memcpy(b.mat,a,sizeof(a));
Mat ans=exp(b,C);
int res=0;
for(int i=0;i<cnt;i++)
res=(res+ans.mat[0][i])%M;
printf("%d\n",res);
return 0;
}