首页 > 代码库 > DNA Sequence(POJ2778 AC自动机dp+矩阵加速)

DNA Sequence(POJ2778 AC自动机dp+矩阵加速)

传送门

DNA Sequence
Time Limit: 1000MS Memory Limit: 65536K
   

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 3ATACAGAA

Sample Output

36

Source

POJ Monthly--2006.03.26,dodo
裸ac自动机。。写出原dp。。构造出矩阵即可。。
  1 #include<set>  2 #include<map>  3 #include<queue>  4 #include<cstdio>  5 #include<cstdlib>  6 #include<cstring>  7 #include<iostream>  8 #include<algorithm>  9 using namespace std; 10 const int SONS=4; 11 const int MOD=100000; 12 const char Hash[5]={ ,A,C,T,G}; 13 #define For(i,n) for(int i=1;i<=n;i++) 14 #define For0(i,n) for(int i=0;i<n;i++) 15 #define Rep(i,l,r) for(int i=l;i<=r;i++) 16 #define Down(i,r,l) for(int i=r;i>=l;i--) 17  18 struct trie{ 19     int sz,ch[11*11][SONS],fn[11*11],next[11*11],q[11*11*3]; 20     trie(){sz=0;} 21     void insert(char *s){ 22         int cur=0,len=strlen(s),id; 23         For0(i,len){ 24             For(j,4) if(s[i]==Hash[j]){id=j-1;break;} 25             if(!ch[cur][id]) ch[cur][id]=++sz;  26             cur=ch[cur][id]; 27         } 28         fn[cur]=1; 29     } 30     void BuildAC(){ 31         int l=0,r=0; 32         For0(i,SONS) 33           if(ch[0][i]) q[++r]=ch[0][i]; 34         while(l<r){ 35             int cur=q[++l]; 36             For0(i,SONS){ 37                 if(ch[cur][i]){ 38                     q[++r]=ch[cur][i]; 39                     next[ch[cur][i]]=ch[next[cur]][i]; 40                     if(fn[next[ch[cur][i]]]) fn[ch[cur][i]]=1; 41                 } 42                 else ch[cur][i]=ch[next[cur]][i]; 43             } 44         } 45     } 46 }ac; 47  48 int m,n,ans,dp[121][121]; 49 char st[11]; 50  51 struct Matrix{ 52     int A[11*11][11*11]; 53     Matrix(){memset(A,0,sizeof(A));} 54 }Unit,Ans; 55  56 Matrix operator * (Matrix A,Matrix B){ 57     Matrix C; 58     For0(i,ac.sz+1) 59       For0(j,ac.sz+1) 60         For0(k,ac.sz+1) 61           C.A[i][j]=(C.A[i][j]+(long long)A.A[i][k]*B.A[k][j])%MOD; 62     return C; 63 } 64  65 void DP(){ 66     For0(i,ac.sz+1) 67         if(!ac.fn[i]) 68           For0(k,SONS){ 69               int cur=ac.ch[i][k]; 70               if(!ac.fn[cur]) Unit.A[i][cur]++;        71           } 72     For0(i,ac.sz+1) Ans.A[i][i]=1; 73     while(n){ 74         if(n&1) Ans=Ans*Unit; 75         Unit=Unit*Unit; 76         n>>=1; 77     } 78     For0(i,ac.sz+1) ans=(ans+Ans.A[0][i])%MOD; 79     printf("%d\n",ans%MOD); 80     /*dp[0][0]=1; 81     For(i,n) 82       For0(j,ac.sz+1){ 83           if(ac.fn[j]) continue; 84           For0(k,SONS){ 85               int cur=ac.ch[j][k]; 86               if(ac.fn[cur]) continue; 87               dp[i][cur]=(dp[i][cur]+dp[i-1][j])%MOD; 88           } 89       } 90     For0(i,ac.sz+1) if(!ac.fn[i]) ans=(ans+dp[n][i])%MOD; 91     printf("%d\n",ans);*/ 92 } 93  94 int main(){ 95     scanf("%d%d",&m,&n); 96     For(i,m){ 97         scanf("%s",&st); 98         ac.insert(st); 99     }100     ac.BuildAC();101     DP();102     return 0;103 }

 

DNA Sequence(POJ2778 AC自动机dp+矩阵加速)