地址:http://poj.org/problem?id=2778
题目:
DNA Sequence
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 15453 | Accepted: 5964 |
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
思路: 用病毒源建立ac自动机,然后所有节点可看做状态转移图。呃,懒得画图了,你们可以百度下。然后根据转移图建立矩阵,之后快速幂即可。
之前一直忘了把end【x】为1的节点的所有子节点的end标记为1,wa的不省人事。
1 #include <queue> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const long long mod=1e5; 7 struct MM 8 { 9 int r,c; 10 long long mx[105][105]; 11 MM(int rr=0,int cc=0){r=rr,c=cc;} 12 friend MM operator *(MM ta,MM tb) 13 { 14 MM tc(ta.r,tb.c); 15 for(int i=0;i<tc.r;i++) 16 for(int j=0;j<tc.c;j++) 17 { 18 tc.mx[i][j]=0; 19 for(int k=0;k<tb.r;k++) 20 tc.mx[i][j]=(tc.mx[i][j]+ta.mx[i][k]*tb.mx[k][j])%mod; 21 } 22 return tc; 23 } 24 friend MM operator ^(MM ta,int num) 25 { 26 MM ret(ta.r,ta.c); //r==c 27 memset(ret.mx,0,sizeof ret.mx); 28 for(int i=0;i<ta.r;i++) ret.mx[i][i]=1; //µ¥Î»¾ØÕó 29 while(num) 30 { 31 if(num&1) 32 ret=ta*ret; 33 num>>=1; 34 ta=ta*ta; 35 } 36 return ret; 37 } 38 }mm; 39 struct AC_auto 40 { 41 const static int LetterSize = 4; 42 const static int TrieSize = 4*1010; 43 44 int tot,root,fail[TrieSize],end[TrieSize],next[TrieSize][LetterSize]; 45 46 int newnode(void) 47 { 48 memset(next[tot],-1,sizeof(next[tot])); 49 end[tot] = 0; 50 return tot++; 51 } 52 53 void init(void) 54 { 55 tot = 0; 56 root = newnode(); 57 } 58 59 int getidx(char x) 60 { 61 if(x=='A')return 0; 62 else if(x=='C')return 1; 63 else if(x=='G')return 2; 64 else return 3; 65 } 66 67 void insert(char *ss) 68 { 69 int len = strlen(ss); 70 int now = root; 71 for(int i = 0; i < len; i++) 72 { 73 int idx = getidx(ss[i]); 74 if(next[now][idx] == -1) 75 next[now][idx] = newnode(); 76 now = next[now][idx]; 77 } 78 end[now]=1; 79 } 80 81 void build(void) 82 { 83 queue<int>Q; 84 fail[root] = root; 85 for(int i = 0; i < LetterSize; i++) 86 if(next[root][i] == -1) 87 next[root][i] = root; 88 else 89 fail[next[root][i]] = root,Q.push(next[root][i]); 90 while(Q.size()) 91 { 92 int now = Q.front();Q.pop(); 93 if(end[fail[now]])end[now]=1; 94 for(int i = 0; i < LetterSize; i++) 95 if(next[now][i] == -1) next[now][i] = next[fail[now]][i]; 96 else 97 fail[next[now][i]] = next[fail[now]][i],Q.push(next[now][i]); 98 } 99 } 100 101 int buildmm(int n) 102 { 103 int cnt = 0; 104 mm.c=mm.r=tot; 105 for(int i = 0; i < tot; i++) 106 for(int j = 0; j < 4; j++) 107 if(!end[next[i][j]]) 108 mm.mx[i][next[i][j]]++; 109 mm=mm ^ n; 110 for(int i = 0; i < tot; i++) 111 cnt = (cnt + mm.mx[0][i]) % mod; 112 return cnt; 113 } 114 }; 115 116 117 AC_auto ac; 118 char sa[20]; 119 int main(void) 120 { 121 int n,m; 122 scanf("%d%d",&n,&m); 123 ac.init(); 124 for(int i=1;i<=n;i++) 125 scanf("%s",sa),ac.insert(sa); 126 ac.build(); 127 printf("%d ",ac.buildmm(m)); 128 return 0; 129 }