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;
}

posted on 2011-03-09 15:26  宇宙吾心  阅读(1158)  评论(0)    收藏  举报

导航