题目链接:http://poj.org/problem?id=2778
题意:有多少种长度n位DNA串不含有指定的病毒片段。
思路:首先,建立自动机,其实也就是一个有向图,则长度为n就好比是在图上走n次,也就是图对应矩阵的n次方。
const int mod=100000;
const int N=205;
struct node
{
int next[4],fail,flag;
void init()
{
clr(next,0);
fail=-1;
flag=0;
}
};
node a[N];
int e,n,m;
char s[N];
int get(char x)
{
if(x=='A') return 0;
else if(x=='T') return 1;
else if(x=='G') return 2;
return 3;
}
void insert(char s[])
{
int i,k,p=0;
for(i=0;s[i];i++)
{
k=get(s[i]);
if(a[p].next[k]==0)
{
a[e].init();
a[p].next[k]=e++;
}
p=a[p].next[k];
}
a[p].flag=1;
}
queue<int> Q;
void build()
{
Q.push(0);
int i,j,k,p,q;
while(!Q.empty())
{
k=Q.front();
Q.pop();
for(i=0;i<4;i++)
{
if(a[k].next[i])
{
p=a[k].next[i];
q=a[k].fail;
while(q!=-1&&!a[q].next[i]) q=a[q].fail;
if(q==-1) a[p].fail=0;
else
{
a[p].fail=a[q].next[i];
a[p].flag|=a[a[p].fail].flag;
}
Q.push(p);
}
else
{
q=a[k].fail;
while(q!=-1&&!a[q].next[i]) q=a[q].fail;
if(q==-1) a[k].next[i]=0;
else a[k].next[i]=a[q].next[i];
}
}
}
}
int b[N][N],d[N][N];
void mul(int a[][N],int b[][N])
{
int i,j,k,c[N][N]={0};
FOR0(k,e) FOR0(i,e) FOR0(j,e)
{
c[i][j]+=(i64)a[i][k]*b[k][j]%mod;
c[i][j]%=mod;
}
FOR0(i,e) FOR0(j,e) a[i][j]=c[i][j];
}
int main()
{
RD(m,n);a[0].init();e=1;
int i,j,k;
FOR0(i,m)
{
RD(s);
insert(s);
}
build();
FOR0(i,e) if(!a[i].flag) FOR0(j,4)
{
k=a[i].next[j];
if(!a[k].flag) b[i][k]++;
}
FOR0(i,e) d[i][i]=1;
while(n)
{
if(n&1) mul(d,b);
mul(b,b);
n>>=1;
}
i64 ans=0;
FOR0(i,e) if(!a[i].flag)ans+=d[0][i];
ans%=mod;
PR(ans);
}