poj 2278 DNASequnce AC自动机

地址: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. 

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

思路: 用病毒源建立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\n",ac.buildmm(m));
128     return 0;
129 }

 

posted @ 2016-10-11 18:34  weeping  阅读(312)  评论(0编辑  收藏  举报