DNA Sequence
Time Limit: 1000ms
Memory Limit: 65536KB
This problem will be judged on PKU. Original ID: 2778
64-bit integer IO format: %lld Java class name: Main
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
解题:真TMD的卡时间,奶奶个熊
1 #include <iostream> 2 #include <stdio.h> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 typedef long long LL; 7 const int mod = 100000; 8 const int maxn = 80; 9 int id[256]; 10 struct Matrix{ 11 int n,m[maxn][maxn]; 12 void init(int sz){ 13 n = sz; 14 memset(m,0,sizeof m); 15 } 16 Matrix(int sz){ 17 init(sz); 18 } 19 void setOne(){ 20 for(int i = 0; i < n; ++i) m[i][i] = 1; 21 } 22 Matrix operator*(const Matrix &rhs){ 23 Matrix ret(n); 24 for(int k = 0; k < n; ++k) 25 for(int i = 0; i < n; ++i) 26 for(int j = 0; j < n; ++j) 27 ret.m[i][j] = (ret.m[i][j] + (LL)m[i][k]*rhs.m[k][j]%mod)%mod; 28 return ret; 29 } 30 void out(){ 31 for(int i = 0; i < n; ++i){ 32 for(int j = 0; j < n; ++j) 33 cout<<m[i][j]<<" "; 34 cout<<endl; 35 } 36 } 37 }; 38 void quickPow(Matrix &base,Matrix &ret,int index){ 39 ret.setOne(); 40 while(index){ 41 if(index&1) ret = ret*base; 42 index >>= 1; 43 base = base*base; 44 } 45 } 46 struct Trie{ 47 int ch[maxn][4],fail[maxn],cnt[maxn],tot; 48 void init(){ 49 tot = 0; 50 newnode(); 51 } 52 int newnode(){ 53 memset(ch[tot],0,sizeof ch[tot]); 54 fail[tot] = cnt[tot] = 0; 55 return tot++; 56 } 57 void insert(char *str,int root = 0){ 58 for(int i = 0; str[i]; ++i){ 59 int &x = ch[root][id[str[i]]]; 60 if(!x) x = newnode(); 61 root = x; 62 } 63 ++cnt[root]; 64 } 65 void build(int root = 0){ 66 queue<int>q; 67 for(int i = 0; i < 4; ++i) 68 if(ch[root][i]) q.push(ch[root][i]); 69 while(!q.empty()){ 70 root = q.front(); 71 q.pop(); 72 cnt[root] += cnt[fail[root]]; 73 for(int i = 0; i < 4; ++i){ 74 int &x = ch[root][i]; 75 if(x){ 76 fail[x] = ch[fail[root]][i]; 77 q.push(x); 78 }else x = ch[fail[root]][i]; 79 } 80 } 81 } 82 int solve(int m){ 83 Matrix a(tot),b(tot); 84 for(int i = 0; i < tot; ++i){ 85 if(cnt[i]) continue; 86 for(int j = 0; j < 4; ++j){ 87 int x = ch[i][j]; 88 if(cnt[x]) continue; 89 ++a.m[i][x]; 90 } 91 } 92 quickPow(a,b,m); 93 int ret = 0; 94 for(int i = 0; i < tot; ++i) 95 ret = (ret + b.m[0][i])%mod; 96 return ret; 97 } 98 }ac; 99 int main(){ 100 for(int i = 0; i < 4; ++i) id["ATCG"[i]] = i; 101 char str[maxn]; 102 int n,m; 103 while(~scanf("%d%d",&n,&m)){ 104 ac.init(); 105 for(int i = 0; i < n; ++i){ 106 scanf("%s",str); 107 ac.insert(str); 108 } 109 ac.build(); 110 printf("%d\n",ac.solve(m)); 111 } 112 return 0; 113 }