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

poj 2778 DNA Sequence ac自动机+矩阵快速幂

2016-05-09 17:47 459 查看
http://poj.org/problem?id=2778

DNA Sequence

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


问题大意:长度为n 由’A’‘G’‘C’‘T‘组成的字符串中不包含这m个字符串的任意一个的组合有多少种;

标记每个字符串的结尾节点为危险节点,如果失败后跳转到的节点是危险节点那么该节点也应为危险节点。

问题转化为长度问n不经过危险节点的走法有多少种。

构造矩阵mat,mat[i][j]为从第i个节点走一步到达第j个节点有多少种走法。求下mat的n次方,即求得ans[][],ans[i][j]为第i个节点走n步到达第j个节点的走法有多少种。

求下ans[0][i]的和就好。

理解好ac自动机和矩阵的含义后还是很好理解的。

后台数据比题意的数据要大一些。一开始一直wa,改了范围就A了。

#include <cstdio>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <vector>
#include <iostream>
#include <algorithm>
#define maxx(a,b) ((a)>(b)?(a):(b))
#define F first
#define S second
using namespace std;

typedef  long long LL;
typedef unsigned long long  uLL;
const int  mod = 100000;
const LL  inf=0x3f3f3f3f;
//const double pi=acos(-1);
const int N=210;//最大点数
const int M=130;// 最大边数

int ans;
int bl[500];
struct mat
{
int  v[210][210];
};
mat c,an;
int size_mat;
mat matrix_mul(mat p1,mat p2,int n,int m,int q)
{
mat t;
memset(t.v,0,sizeof(t.v));
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(p1.v[i][j])
for(int k=0; k<q; k++)
{
int tep=((long long )p1.v[i][j]*p2.v[j][k])%mod;
t.v[i][k]=(t.v[i][k]+tep)%mod;
}
return t;
}
mat matrix_mi(mat p,int n,int k)
{
mat t;
memset(t.v,0,sizeof(t.v));
for(int i=0; i<n; i++)
{
t.v[i][i]=1;
}
while(k)
{
if(k&1)
t=matrix_mul(t,p,n,n,n);
k>>=1;
p=matrix_mul(p,p,n,n,n);
}
return t;
}
struct Trie
{
int next
[4],fail
,end
;
int root,L;
int nownode()
{
for(int i=0; i<4; i++)
next[L][i]=-1;
end[L++]=0;
return L-1;
}
void init()
{
L=0;
root=nownode();
}
void insert(char buf[],int k)
{
int len=strlen(buf);
int  now=root;
for(int i=0; i<len; i++)
{
if(next[now][bl[buf[i]]]==-1)
next[now][bl[buf[i]]]=nownode();
now=next[now][bl[buf[i]]];
}
end[now]=1;
}
void build()
{
queue<int>Q;
fail[root]=root;
for(int i=0; i<4; i++)
if(next[root][i]==-1)
next[root][i]=root;
else
{
fail[next[root][i]]=root;
Q.push(next[root][i]);
}
while(!Q.empty())
{
int now=Q.front();
Q.pop();
if(end[fail[now]]==1)
end[now]=1;
for(int i=0; i<4; i++)
{
if(next[now][i]==-1)
next[now][i]=next[fail[now]][i];
else
{
fail[next[now][i]]=next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
}
int  gett()
{
for(int i=0; i<L; i++)
{
for(int j=0; j<4; j++)
{
if(end[next[i][j]]==0)
c.v[i][next[i][j]]++;
}
}
return L;
}
};
Trie ac;
char str[500];
int main()
{
#ifdef LOCAL
freopen("date.in","r",stdin);
freopen("date.out","w",stdout);
#endif
int m,n;
bl['A']=0;
bl['G']=1;
bl['C']=2;
bl['T']=3;

while(scanf("%d%d",&m,&n)!=EOF)
{
ac.init();
for(int  i=1; i<=m; i++)
{
scanf("%s",str);
ac.insert(str,i);
}
ac.build();
memset(c.v,0,sizeof(c.v));
size_mat=ac.gett();

an=matrix_mi(c,size_mat,n);
ans=0;
// for(int i=0;i<size_mat;i++)
// {
//     puts("");
//     for(int j=0;j<size_mat;j++)
//         printf("%d ",an.v[i][j]);
// }
for(int i=0;i<size_mat;i++)
{
ans+=an.v[0][i];
ans%=mod;
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: