DNA Sequence
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14758 Accepted: 5716 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 AASample Output
36
【分析】
之前做过的题。 建立一个AC自动机,然后把每个字符串的最后一位所在的节点标黑。(就是把mark变为1) 然后用AC自动机建立矩阵array[i][j]表示从i走到j的方案数,然后利用矩阵乘法的性质,用快速幂求出矩阵的M次幂即可。
代码依然丑:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 #define Maxn 1010 9 #define LL long long 10 #define Mod 100000 11 12 struct node 13 { 14 int x,fail; 15 int son[6]; 16 bool mark; 17 }t[Maxn];int tot=0; 18 19 struct Matrix 20 { 21 LL a[110][110]; 22 }ay,ut; 23 24 void upd(int x) 25 { 26 t[x].mark=0; 27 memset(t[x].son,0,sizeof(t[x].son)); 28 } 29 30 Matrix h; 31 void clear(int id) 32 { 33 for(int i=0;i<=tot;i++) 34 for(int j=0;j<=tot;j++) 35 if(id==1) ay.a[i][j]=0; 36 else h.a[i][j]=0; 37 } 38 39 int m,n; 40 char s[Maxn]; 41 42 void read_trie() 43 { 44 scanf("%s",s+1); 45 int len=strlen(s+1); 46 int now=0; 47 for(int i=1;i<=len;i++) 48 { 49 int ind; 50 if(s[i]=='A') ind=1; 51 else if(s[i]=='T') ind=2; 52 else if(s[i]=='C') ind=3; 53 else ind=4; 54 if(!t[now].son[ind]) 55 { 56 t[now].son[ind]=++tot,upd(tot); 57 } 58 now=t[now].son[ind]; 59 if(i==len) t[now].mark=1; 60 } 61 } 62 63 queue<int > q; 64 void build_AC() 65 { 66 while(!q.empty()) q.pop(); 67 q.push(0); 68 while(!q.empty()) 69 { 70 int now=q.front();q.pop(); 71 int f=t[now].fail; 72 for(int i=1;i<=4;i++) 73 { 74 if(t[now].son[i]) 75 { 76 q.push(t[now].son[i]); 77 t[t[now].son[i]].fail=now?t[f].son[i]:0; 78 if(t[t[t[now].son[i]].fail].mark) t[t[now].son[i]].mark=1; 79 } 80 else t[now].son[i]=t[f].son[i]; 81 if(t[t[now].son[i]].mark!=1) ay.a[now][t[now].son[i]]++; 82 } 83 } 84 } 85 86 Matrix mul(Matrix a,Matrix b) 87 { 88 clear(2); 89 for(int i=0;i<=tot;i++) 90 for(int j=0;j<=tot;j++) 91 for(int k=0;k<=tot;k++) 92 { 93 h.a[i][j]=(h.a[i][j]+a.a[i][k]*b.a[k][j])%Mod; 94 95 } 96 return h; 97 } 98 99 void qpow(int k) 100 { 101 while(k) 102 { 103 if(k&1) ut=mul(ut,ay); 104 ay=mul(ay,ay); 105 k>>=1; 106 } 107 } 108 109 void init() 110 { 111 scanf("%d%d",&m,&n); 112 tot=0;upd(0); 113 for(int i=1;i<=m;i++) 114 { 115 read_trie(); 116 } 117 clear(1); 118 build_AC(); 119 for(int i=0;i<=tot;i++) 120 for(int j=0;j<=tot;j++) 121 ut.a[i][j]=i==j?1:0; 122 123 qpow(n); 124 LL ans=0; 125 for(int i=0;i<=tot;i++) ans=(ans+ut.a[0][i])%Mod; 126 printf("%I64d\n",ans); 127 } 128 129 int main() 130 { 131 init(); 132 return 0; 133 }