POJ 2778 DNA Sequence

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 }
View Code

 

posted @ 2015-11-04 23:20  狂徒归来  阅读(301)  评论(0编辑  收藏  举报