POJ 3691 DNA Sequence (AC自动机 + 矩阵 有bug,待修改)
DNA Sequence
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 9889 | Accepted: 3712 |
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.
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.
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
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=110; const int mod=100000; struct Trie{ int ok; int fail; int next[4]; void Init(){ ok=0; fail=-1; memset(next,-1,sizeof(next)); } }a[N]; char wrd[30]; char str[N]; int n,m,cnt,q[N]; int find(char ch){ switch(ch){ case 'A':return 0; case 'C':return 1; case 'T':return 2; case 'G':return 3; } return 0; } void InsertTrie(char *str){ int p=0; for(int i=0;str[i]!='\0';i++){ int id=find(str[i]); if(a[p].ok) break; if(a[p].next[id]==-1){ a[p].next[id]=cnt++; a[cnt-1].Init(); } p=a[p].next[id]; } a[p].ok++; } void AC_automation(){ int head=0,tail=0; q[tail++]=0; int cur=0,tmp; while(head<tail){ cur=q[head++]; for(int i=0;i<4;i++){ tmp=a[cur].next[i]; if(tmp!=-1){ if(cur==0) a[tmp].fail=0; else{ a[tmp].fail=a[a[cur].fail].next[i]; if(a[a[tmp].fail].ok) a[tmp].ok++; } q[tail++]=a[cur].next[i]; }else{ if(cur==0) a[cur].next[i]=0; else a[cur].next[i]=a[a[cur].fail].next[i]; } } } } struct Matrix{ long long m[110][110]; }; Matrix init,unit; void Init(){ memset(init.m,0,sizeof(init.m)); for(int i=0;i<cnt;i++) if(!a[i].ok) for(int j=0;j<4;j++){ if(a[a[i].next[j]].ok==0) init.m[i][a[i].next[j]]++; } //if(a[*a[i].next[j]].ok==0) //init.m[i][*a[i].next[j]]++; for(int i=0;i<cnt;i++) for(int j=0;j<cnt;j++) unit.m[i][j]=(i==j)?1:0; } Matrix Mul(Matrix a,Matrix b){ Matrix c; for(int i=0;i<cnt;i++) for(int j=0;j<cnt;j++){ c.m[i][j]=0; for(int k=0;k<cnt;k++) c.m[i][j]=(a.m[i][k]*b.m[k][j])%mod; c.m[i][j]%=mod; } return c; } Matrix Pow(Matrix a,Matrix b,int k){ while(k){ if(k&1){ b=Mul(a,b); } a=Mul(a,a); k>>=1; } return b; } int main(){ freopen("input.txt","r",stdin); while(~scanf("%d%d",&n,&m)){ cnt=1; a[0].Init(); for(int i=0;i<n;i++){ scanf("%s",wrd); InsertTrie(wrd); } AC_automation(); Init(); Matrix res=Pow(init,unit,m); long long ans=0; for(int i=0;i<cnt;i++) if(a[i].ok==0) ans=(ans+res.m[0][i])%mod; cout<<ans<<endl; } return 0; }

浙公网安备 33010602011771号