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 4 3 AT AC AG AA Sample Output 36 Source |
[Submit] [Go Back] [Status] [Discuss]
非常经典的AC自动机+矩阵。。。。。
节点比较少,需要构造的串很长。。。所以直接把各种转移状态记录到矩阵里,用快速幂解决。。。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> using namespace std; const int maxn=10000; const int MOD=100000; int idx(char x) { if(x==‘A‘) return 0; else if(x==‘T‘) return 1; else if(x==‘C‘) return 2; else if(x==‘G‘) return 3; } int ch[maxn][5],fail[maxn],end[maxn]; int root,sz; char str[200]; int newnode() { memset(ch[sz],-1,sizeof(ch[sz])); end[sz++]=0; return sz-1; } void ac_init() { sz=0; root=newnode(); } void ac_insert(char str[]) { int len=strlen(str); int now=root; for(int i=0;i<len;i++) { if(ch[now][idx(str[i])]==-1) ch[now][idx(str[i])]=newnode(); now=ch[now][idx(str[i])]; } end[now]++; } void ac_build() { queue<int> q; fail[root]=root; for(int i=0;i<4;i++) { int& temp=ch[root][i]; if(temp==-1) { ch[root][i]=root; } else { fail[ch[root][i]]=root; q.push(ch[root][i]); } } while(!q.empty()) { int now=q.front(); q.pop(); end[now]+=end[fail[now]]; for(int i=0;i<4;i++) { if(ch[now][i]==-1) { ch[now][i]=ch[fail[now]][i]; } else { fail[ch[now][i]]=ch[fail[now]][i]; q.push(ch[now][i]); } } } } int n,m; struct MARTRIX { int _x,_y; long long int martrix[200][200]; MARTRIX () {} MARTRIX (int n) { _x=_y=n; memset(martrix,0,sizeof(martrix)); } void getONE(int n) { for(int i=0;i<n;i++) { martrix[i][i]=1; } } MARTRIX operator * (const MARTRIX& b) const { int n=b._x; MARTRIX ret(n); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { int temp=0; for(int k=0;k<n;k++) { temp=(temp+martrix[i][k]*b.martrix[k][j])%MOD; } ret.martrix[i][j]=temp%MOD; } } return ret; } }; MARTRIX QuickPOW(MARTRIX M,int n) { MARTRIX ans; ans.getONE(M._x); while(n) { if(n&1) { ans=ans*M; } M=M*M; n>>=1; } return ans; } int main() { while(scanf("%d%d",&m,&n)!=EOF) { ac_init(); for(int i=0;i<m;i++) { scanf("%s",str); ac_insert(str); } ac_build(); MARTRIX mat(sz); for(int i=0;i<sz;i++) { if(end[i]) continue; for(int j=0;j<4;j++) { int p=ch[i][j]; if(end[p]||end[fail[p]]) continue; mat.martrix[i][p]++; } } MARTRIX ret=QuickPOW(mat,n); long long int ans=0; for(int i=0;i<sz;i++) { ans=(ans+ret.martrix[0][i])%MOD; } printf("%I64d\n",ans); } return 0; }
POJ 2778 DNA Sequence,布布扣,bubuko.com
原文:http://blog.csdn.net/ck_boss/article/details/23716325