您的位置:首页 > 产品设计 > UI/UE

POJ 题目2778 DNA Sequence(AC自动机,矩阵快速幂)

2015-08-10 01:04 555 查看
DNA Sequence

Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 13040Accepted: 4964
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

题目大意:长度为n不出现这些子串的个数。。

build_ac()的时候略有不同,

具体讲解,/article/2566293.html

看了好多代码,都不是很一样,看别人解析看了好久还是有些不大懂,主要是build_acde时候,找了一个和我写ac自动机比较像的大牛,按人家代码写了一下,先收藏一下吧

ac代码

#include<stdio.h>
#include<string.h>
#define mod 100000
char key[15];
int head,tail,cnt=0;
struct node
{
node *fail;
node *next[4];
int isword,kind;
}*q[500050],s[500050];
node *newnode()
{
node *temp=&s[cnt];
temp->fail=NULL;
temp->kind=cnt++;
for(int i=0;i<4;i++)
temp->next[i]=NULL;
return temp;
}
node *root;
int id(char c)
{
if(c=='A')
return 0;
else
if(c=='T')
return 1;
if(c=='C')
return 2;
return 3;
}
void insert(char *s)
{
int temp,len,i;
node *p=root;
len=strlen(s);
for(i=0;i<len;i++)
{
temp=id(s[i]);
if(p->next[temp]==NULL)
p->next[temp]=newnode();
p=p->next[temp];
}
p->isword=1;
}
void build_ac()
{
q[tail++]=root;
while(head!=tail)
{
node *p=q[head++];
node *temp=NULL;
for(int i=0;i<4;i++)
{
if(p->next[i]!=NULL)
{
if(p==root)
p->next[i]->fail=root;
else
{
temp=p->fail;
//  while(temp!=NULL)
//{
//  if(temp->next[i]!=NULL)
//{
p->next[i]->fail=temp->next[i];
//  break;
//}
if(p->next[i]->fail->isword)
p->next[i]->isword=1;
//temp=temp->fail;
}
q[tail++]=p->next[i];
}
else
{
if(p==root)
p->next[i]=root;
else
{
p->next[i]=p->fail->next[i];
}
}
}
}
}
struct s
{
__int64 map[110][110];
}mm;
struct s muti(struct s a,struct s b)
{
struct	s ans;
int i,j;
memset(ans.map,0,sizeof(ans.map));
int k;
for(i=0;i<cnt;i++)
{
for(k=0;k<cnt;k++)
{
if(a.map[i][k]!=0)
{
for(j=0;j<cnt;j++)
{
ans.map[i][j]+=a.map[i][k]*b.map[k][j];
if(ans.map[i][j]>=mod)
ans.map[i][j]%=mod;
}
}
}
}
return ans;
}
struct s qpow(struct s a,int n)
{
int i,j,k;
struct s ans;
//	printf("MMMMMMMM\n");
memset(ans.map,0,sizeof(ans.map));
for(i=0;i<cnt;i++)
ans.map[i][i]=1;
while(n)
{
if(n&1)
ans=muti(ans,a);
a=muti(a,a);
n>>=1;

}
return ans;
}
int main()
{
int n,m;
while(scanf("%d%d",&m,&n)!=EOF)
{
int i,j;
head=tail=0;
cnt=0;
root=newnode();

for(i=0;i<m;i++)
{
scanf("%s",key);
insert(key);
}
build_ac();
memset(mm.map,0,sizeof(mm.map));
//	printf("%d\n",cnt);
for(i=0;i<cnt;i++)
{
for(j=0;j<4;j++)
{
node *son=s[i].next[j];
if(!son->isword&&!s[i].isword)
{
mm.map[i][son->kind]++;
}
}
}
mm=qpow(mm,n);
__int64 ans=0;
for(i=0;i<cnt;i++)
{
//	for(j=0;j<cnt;j++)
//	{
ans+=mm.map[0][i];
ans%=mod;
//	}
}
printf("%I64d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: