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

poj 2778 DNA Sequence(AC自动机+矩阵快速幂)

2013-10-25 21:07 519 查看
DNA Sequence

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

题解:建立自动机的dfa有向图,每一个节点代表一个有效点,用一个矩阵代表状态转移,然后用矩阵快速幂求解,结果是要从结点出发到所有结点的状态数

#include<stdio.h>
#include<string.h>
#include<queue>
#define mod 100000
using namespace std;
char str[18];
int m,n,all;
struct tire{
int next[4],fail,e;
void init()
{
fail=e=0;
memset(next,0,sizeof(next));
}
}t[418];
struct matrix{
int a[118][118];
}e,res;
int change(char c)
{
if(c=='A') return 0;
else if(c=='T') return 1;
else if(c=='C') return 2;
return 3;
}
void myinsert(char *s)
{
int i=0,now=0,temp;

for(;s[i];i++)
{
temp=change(s[i]);
if(!t[now].next[temp])
{
t[now].next[temp]=++all;
t[all].init();
}
now=t[now].next[temp];
}
t[now].e=1;
}
void mybuild()
{
int i=0,now=0;
queue<int>q;

for(i=0;i<4;i++)
{
if(!t[now].next[i]) continue;
else
{
t[t[now].next[i]].fail=0;
q.push(t[now].next[i]);
}
}
while(!q.empty())
{
now=q.front();
q.pop();
for(i=0;i<4;i++)
{
if(!t[now].next[i]) t[now].next[i]=t[t[now].fail].next[i];
else
{
t[t[now].next[i]].fail=t[t[now].fail].next[i];
if(t[t[t[now].next[i]].fail].e) t[t[now].next[i]].e=1;
q.push(t[now].next[i]);
}
}
}
}
void getmat()
{
int i,j;

memset(res.a,0,sizeof(res.a));
memset(e.a,0,sizeof(e.a));
for(i=0;i<=all;i++) res.a[i][i]=1;
for(i=0;i<=all;i++)
{
for(j=0;j<4;j++)
{
if(!t[t[i].next[j]].e) e.a[i][t[i].next[j]]++;
}
}
}
struct matrix mult(struct matrix x,struct matrix y)
{
struct matrix temp;
int i,j,k;

memset(temp.a,0,sizeof(temp.a));
for(i=0;i<=all;i++)
{
for(j=0;j<=all;j++)
{
if(x.a[i][j]) for(k=0;k<=all;k++)
{
int tmp=((long long)x.a[i][j]*y.a[j][k])%mod;
temp.a[i][k]=(temp.a[i][k]+tmp)%mod;
}
}
}

return temp;
};
void fpow(int x)
{
while(x)
{
if(x&1) res=mult(res,e);
e=mult(e,e);
x>>=1;
}
}
int main()
{
int i,ans;

//freopen("t.txt","r",stdin);
while(scanf("%d%d",&m,&n)>0)
{
t[0].init();
for(all=i=0;i<m;i++)
{
scanf("%s",str);
myinsert(str);
}
mybuild();
getmat();
fpow(n);
for(ans=i=0;i<=all;i++) ans=(ans+res.a[0][i])%mod;
printf("%d\n",ans);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: