POJ 2778 DNA Sequence(AC自动机+矩阵快速幂+dp)
2018-02-20 10:02
375 查看
DNA Sequence
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
Sample Output
Source
POJ Monthly--2006.03.26,dodo
大致题意,与之前那道题目差不多,也是由指定的一些字母构成的字符串,不能够包换一些不合法的字符,再告诉你一个长度,问你一共有多少个合法的字符串。但不同的是,这道题目的长度可以很长。
上一道题目,我们介绍了用dp的方法去解决,但是这题面对这么长的长度,显然是不可取的。但是我们回顾一下上一道题目dp的过程,dp[i][j]表示到达AC自动机上的j点走了i步时的方案数,最后要求的是 Σdp
[j],即到达每个合法点走了n步时的方案数总和。而在图论中,邻接矩阵的乘法、次方,恰好可以表示一个人在图中走了确定的某个步数之后的方案数。所以说对于这题,我们可以把AC自动机想象成一个有向图,然后在这个有向图上面走长度那么多的步数。AC自动机上的连边就是这个有向图中的连边,然后对于那些不合法单词,我们还是一样把末尾节点特殊标记为不可达,因为根据AC自动机的性质,能够到达这个点就一定能够构成至少一个不合法单词。构造出矩阵之后,直接矩阵快速幂即可。
具体见代码:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 18472 | Accepted: 7109 |
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
大致题意,与之前那道题目差不多,也是由指定的一些字母构成的字符串,不能够包换一些不合法的字符,再告诉你一个长度,问你一共有多少个合法的字符串。但不同的是,这道题目的长度可以很长。
上一道题目,我们介绍了用dp的方法去解决,但是这题面对这么长的长度,显然是不可取的。但是我们回顾一下上一道题目dp的过程,dp[i][j]表示到达AC自动机上的j点走了i步时的方案数,最后要求的是 Σdp
[j],即到达每个合法点走了n步时的方案数总和。而在图论中,邻接矩阵的乘法、次方,恰好可以表示一个人在图中走了确定的某个步数之后的方案数。所以说对于这题,我们可以把AC自动机想象成一个有向图,然后在这个有向图上面走长度那么多的步数。AC自动机上的连边就是这个有向图中的连边,然后对于那些不合法单词,我们还是一样把末尾节点特殊标记为不可达,因为根据AC自动机的性质,能够到达这个点就一定能够构成至少一个不合法单词。构造出矩阵之后,直接矩阵快速幂即可。
具体见代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <vector> #include <queue> #define INF 0x3f3f3f3f #define LL long long #define mod 100000 #define N 105 using namespace std; int h[256],n,m,p; struct AC_automation { struct node{int fail,cnt,ch[4];} T[110]; int tot,root; void init() { tot=root=0; memset(T,0,sizeof(T)); } void ins(char* x) { int o=root; for(int k=0;x[k];k++) { int c=h[x[k]]; if(!T[o].ch[c]) T[o].ch[c]=++tot; o=T[o].ch[c]; } T[o].cnt++; } void get_fail() { queue<int> q; q.push(root); while(!q.empty()) { int o=q.front(); T[o].cnt=T[o].cnt|T[T[o].fail].cnt; for(int i=0;i<4;i++) { if (!T[o].ch[i]) { T[o].ch[i]=T[T[o].fail].ch[i]; continue; } if (o!=root) { int fa=T[o].fail; while(fa&&!T[fa].ch[i]) fa=T[fa].fail; T[T[o].ch[i]].fail=T[fa].ch[i]; } else T[T[o].ch[i]].fail=root; q.push(T[o].ch[i]); } q.pop(); } } } AC; struct matrix { LL a ; void init(int x){memset(a,0,sizeof(a));} friend matrix operator *(matrix x,matrix y) { matrix ans; for(int i=0;i<=p;i++) for(int j=0;j<=p;j++) { ans.a[i][j]=0; for(int k=0;k<=p;k++) ans.a[i][j]+=x.a[i][k]*y.a[k][j]%mod; ans.a[i][j]%=mod; } return ans; } friend matrix operator ^(matrix x,LL y) { matrix ans; if (y==0) { memset(ans.a,0,sizeof(ans.a)); for(int i=1;i<=p;i++) ans.a[i][i]=1; return ans; } else while ((y&1)==0) y>>=1,x=x*x; ans=x; y>>=1; for(;y!=0;y>>=1) { x=x*x; if ((y&1)!=0) ans=ans*x; } return ans; } } x; int main() { h['A']=0;h['T']=1; h['C']=2;h['G']=3; while(~scanf("%d%d",&n,&m)) { AC.init();char s[15]; for(int i=1;i<=n;i++) { scanf("%s",s); AC.ins(s); } p=AC.to 1062e t; AC.get_fail(); x.init(AC.tot); for(int i=0;i<=AC.tot;i++) if (!AC.T[i].cnt) for(int j=0;j<4;j++) { int k=AC.T[i].ch[j]; if (!AC.T[k].cnt) x.a[i][k]++; } x=x^m; int ans=0; for(int i=0;i<=AC.tot;i++) ans=(ans+x.a[0][i])%mod; cout<<ans<<endl; } return 0; }
相关文章推荐
- POJ 2778 DNA Sequence (AC自动机,矩阵乘法)
- poj 2778 DNA Sequence 【AC自动机 + 矩阵加速】
- POJ 2778 DNA Sequence(AC自动机+矩阵快速幂)
- POJ 2778 DNA Sequence (AC自动机)
- poj 2778 DNA Sequence(AC自动机 + 矩阵快速幂)
- poj -- 2778 DNA Sequence && hdu -- 2243 考研路茫茫——单词情结(AC自动机 + 矩阵)
- POJ - 2778_DNA Sequence_AC自动机&&矩阵快速幂
- poj 2778 DNA Sequence
- Poj 2778 DNA Sequence (AC自动机+矩阵)
- POJ 2778:DNA Sequence(AC自动机+矩阵快速幂)
- POJ 2778 DNA Sequence (AC自动机+DP+矩阵)
- 线性代数(矩阵乘法):POJ 2778 DNA Sequence
- POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]
- poj_2778_DNA Sequence(AC自动机+矩阵)
- POJ 2778 DNA Sequence
- POJ 2778 DNA Sequence(AC自动机+矩阵快速幂)
- POJ 2778 DNA Sequence(AC自动机+矩阵幂DP)
- POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]
- (AC自动机/矩阵快速幂)poj 2778 DNA Sequence
- POJ-2778 DNA Sequence(AC自动机+矩阵快速幂)