poj2778 DNA Sequence

24 篇文章 0 订阅
6 篇文章 0 订阅
DNA Sequence
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 18514 Accepted: 7123
Description


It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to analyze a segment of DNA Sequence,For example, if a animal's DNA sequence contains segment ATC then it may mean that the animal may have a genetic disease. Until now scientists have found several those segments, the problem is how many kinds of DNA sequences of a species don't contain those segments. 


Suppose that DNA sequences of a species is a sequence that consist of A, C, T and G,and the length of sequences is a given integer n. 
Input


First line contains two integer m (0 <= m <= 10), n (1 <= n <=2000000000). Here, m is the number of genetic disease segment, and n is the length of sequences. 


Next m lines each line contain a DNA genetic disease segment, and length of these segments is not larger than 10. 
Output


An integer, the number of DNA sequences, mod 100000.
Sample Input


4 3
AT
AC
AG
AA
Sample Output


36
Source


POJ Monthly--2006.03.26,dodo




题目大意:给出m个长度不大于10的仅由"A""C""G""T"组成的串,问一个长度为n的仅由"A""C""G""T"组成的串且前面m个串没在其中出现有几种可能。


题解:AC自动机后用矩阵快速幂优化dp


代码:

#include<cstdio>    
#include<iostream>    
#include<algorithm>      
#include<cstring>      
#include<cmath>      
#include<queue>
using namespace std;
struct aaa{
	int next[4],fail;
}f[1000000];
long long b[1000][1000],c[1000][1000],d[1000][1000],ans;
int n,m,tot,g[1000000],q[1000000];
int DNA(char s){
	if(s=='A')return 0;
	if(s=='C')return 1;
	if(s=='G')return 2;
	if(s=='T')return 3;
}
void chu(int x){
	memset(f[x].next,-1,sizeof(f[x].next));
}
void add(char s[]){
	int t,i,len=strlen(s),k=0;
	for(i=0;i<len;i++){
		t=DNA(s[i]);
		if(f[k].next[t]==-1){
			tot++;
			chu(tot);
			f[k].next[t]=tot;
		}
		k=f[k].next[t];
	}
	g[k]=1;
}
void build_AC(){
	int l=0,r=0,i,k,o;
	f[0].fail=0;
	for(i=0;i<4;i++){
		if(f[0].next[i]==-1)f[0].next[i]=0;
		 else{
		 	f[f[0].next[i]].fail=0;
		 	r++;
		 	q[r]=f[0].next[i];
		 }
	}
	while(l<r){
		l++;
		o=q[l];
		if(g[f[o].fail])g[o]=1;
		for(i=0;i<4;i++){
			if(f[o].next[i]==-1){
			f[o].next[i]=f[f[o].fail].next[i];continue;}
			k=f[o].fail;
		    f[f[o].next[i]].fail=f[f[o].fail].next[i];
			r++;
			q[r]=f[o].next[i];
		}
	}
}
int main(){
	int i,j,k;
	char s[10000];
	chu(0);
	scanf("%d%d",&m,&n);
	for(i=1;i<=m;i++){
		scanf("%s",&s);
		add(s);
	}
	build_AC();
	for(i=0;i<=tot;i++)
	 for(j=0;j<4;j++){
	  if((!g[i])&&(!g[f[i].next[j]])){
	  c[i][f[i].next[j]]++;}}
	for(i=0;i<=tot;i++)
	 b[i][i]=1;  
	while(n){
		if(n%2==1){
			memset(d,0,sizeof(d));
			for(i=0;i<=tot;i++)
			 for(j=0;j<=tot;j++){
			  for(k=0;k<=tot;k++)
			   d[i][j]=d[i][j]+b[i][k]*c[k][j];
			   d[i][j]%=100000;
	}
		    for(i=0;i<=tot;i++)
		     for(j=0;j<=tot;j++)b[i][j]=d[i][j];
		}
		memset(d,0,sizeof(d));
		for(i=0;i<=tot;i++)
		 for(j=0;j<=tot;j++){
		  for(k=0;k<=tot;k++)
		   d[i][j]=d[i][j]+c[i][k]*c[k][j]; 
		   d[i][j]%=100000;
	}
	for(i=0;i<=tot;i++)
	 for(j=0;j<=tot;j++)c[i][j]=d[i][j];
		n/=2;
	}
	for(i=0;i<=tot;i++){
	ans=(ans+b[0][i])%100000;}
	printf("%lld",ans);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值