poj 2778
自动机+矩阵乘。
代码:
#include<iostream>
#include<fstream>
using namespace std;
struct e{
int p[5];
int end;
}trie[101];
int m,K,n;
int hash[128];
int state=1;
long long s;
int f[101];
void build(char c[]){
int i,j=0,k;
for(i=1;;)
{
if(trie[i].p[hash[c[j]]]==0)
trie[i].p[hash[c[j]]]=++state;
i=trie[i].p[hash[c[j]]];
j++;
if(j>=strlen(c))
break;
}
trie[i].end=1;
}
void ac(){
int q[111];
int l=0,r=0;
int i,j,k;
for(i=0;i<n;i++)
if(trie[1].p[i])
{
q[++r]=trie[1].p[i];
f[trie[1].p[i]]=1;
}
else
{
trie[1].p[i]=1;
}
while(l<r){
i=q[++l];
for(j=0;j<n;j++)
{
if(trie[i].p[j])
{
q[++r]=trie[i].p[j];
k=f[i];
while(!trie[k].p[j])
k=f[k];
f[trie[i].p[j]]=trie[k].p[j];
trie[trie[i].p[j]].end|=trie[trie[k].p[j]].end;
}
}
}
}
long long map[101][101],map1[101][101],map2[101][101];
void solve(long long s){
int i,j,k;
if(s==1)
for(i=1;i<=state;i++)
for(j=1;j<=state;j++)
map1[i][j]=map[i][j];
else
{
solve(s/2);
for(i=1;i<=state;i++)
for(j=1;j<=state;j++)
for(k=1,map2[i][j]=0;k<=state;k++)
{
map2[i][j]+=map1[i][k]*map1[k][j];
map2[i][j]%=100000;
}
if(s/2*2==s)
{
for(i=1;i<=state;i++)
for(j=1;j<=state;j++)
map1[i][j]=map2[i][j];
}
else
{
for(i=1;i<=state;i++)
for(j=1;j<=state;j++)
for(k=1,map1[i][j]=0;k<=state;k++)
{
map1[i][j]+=map2[i][k]*map[k][j];
map1[i][j]%=100000;
}
}
}
}
void loop(){
int i,j,k;
for(i=1;i<=state;i++)
if(trie[i].end)
continue;
else
{
for(j=0;j<n;j++)
if(trie[i].p[j])
{
k=trie[i].p[j];
if(trie[k].end==0)
map[i][k]++;
}
else
{
k=f[i];
while(!trie[k].p[j])
k=f[k];
if(!trie[trie[k].p[j]].end)
{
k=trie[k].p[j];
map[i][k]++;
}
}
}
}
void read(){
// ifstream cin("in.txt");
int i,j,k;
char c[20];
cin>>m>>s;
hash['A']=0;
hash['C']=1;
hash['T']=2;
hash['G']=3;
n=4;
for(i=1;i<=m;i++)
{
cin>>c;
build(c);
}
ac();
loop();
solve(s);
long long ans=0;
for(i=1;i<=state;i++)
{
ans+=map1[1][i];
ans%=100000;
}
cout<<ans<<endl;
}
int main(){
read();
return 0;
}
浙公网安备 33010602011771号