poj2778DNA Sequence (AC自动机+矩阵快速幂)

转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud

 

DNA Sequence
Time Limit: 1000MS   Memory Limit: 65536K

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

Source

 
题意
构造一个长度为n的DNA序列,要求其中不得出现m个禁止的字符串中的任意一个
一道很明显的矩阵快速幂的题。先通过AC自动机得出一个邻接矩阵,然后快速幂。
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <queue>
  5 using namespace std;
  6 #define REP(A,X) for(int A=0;A<X;A++)
  7 #define MAXN    100010
  8 
  9 int p[MAXN][4];
 10 int tail[MAXN];
 11 int fail[MAXN];
 12 int root,tot;
 13 const long long MOD =100000;
 14 struct Matrix{
 15     int n;
 16     int mat[110][110];
 17     Matrix(){}
 18     Matrix(int _n){
 19         n=_n;
 20         REP(i,n)
 21             REP(j,n)mat[i][j]=0;
 22     }
 23     void init()
 24     {
 25         REP(i,tot)
 26         REP(j,tot)mat[i][j]=0;
 27     }
 28     void unit()
 29     {
 30         REP(i,tot)
 31         REP(j,tot)mat[i][j]=i==j?1:0;
 32     }
 33     Matrix operator *(const Matrix &a)const {
 34         Matrix ret(n);
 35         REP(i,n)
 36         REP(j,n)
 37         REP(k,n)
 38         {
 39             int tmp=(long long)mat[i][k]*a.mat[k][j]%MOD;
 40             ret.mat[i][j]=(ret.mat[i][j]+tmp)%MOD;
 41         }
 42         return ret;
 43     }
 44 };
 45 int newnode()
 46 {
 47     REP(i,4)p[tot][i]=-1;
 48     tail[tot++]=0;
 49     return tot-1;
 50 }
 51 void init()
 52 {
 53     tot=0;
 54     root=newnode();
 55 }
 56 int a[MAXN];
 57 void insert(char *s){
 58     int len=strlen(s);
 59     REP(i,len)
 60     {
 61         if(s[i]=='A')a[i]=0;
 62         else if(s[i]=='C')a[i]=1;
 63         else if(s[i]=='G')a[i]=2;
 64         else if(s[i]=='T')a[i]=3;
 65     }
 66     int now= root ;
 67     REP(i,len)
 68     {
 69         if(p[now][a[i]]==-1)p[now][a[i]]=newnode();
 70         now=p[now][a[i]];
 71     }
 72     tail[now]++;
 73 }
 74 void build()
 75 {
 76     int now=root;
 77     queue<int >q;
 78     fail[root]=root;
 79     REP(i,4){
 80         if(p[root][i]==-1){
 81             p[root][i]=root;
 82         }
 83         else {
 84             fail[p[root][i]]=root;
 85             q.push(p[root][i]);
 86         }
 87     }
 88     while(!q.empty())
 89     {
 90         now =q.front();
 91         q.pop();
 92         if(tail[fail[now]])tail[now]=1;
 93         REP(i,4){
 94             if(p[now][i]==-1){
 95                 p[now][i]=p[fail[now]][i];
 96             }else{
 97                 fail[p[now][i]]=p[fail[now]][i];
 98                 q.push(p[now][i]);
 99             }
100         }
101     }
102 }
103 char s[MAXN];
104 Matrix Mat;
105 int main()
106 {
107     ios::sync_with_stdio(false);
108     int n,m;
109     while(cin>>m>>n){
110         init();
111         REP(i,m){
112             cin>>s;
113             insert(s);
114         }
115         build();
116         Mat.n=tot;
117         Mat.init();
118         REP(i,tot){
119             REP(j,4){
120                 if(!tail[p[i][j]])Mat.mat[i][p[i][j]]++;
121             }
122         }
123         Matrix tmp(tot);
124         tmp.unit();
125         while(n){
126             if(n&1)tmp=tmp*Mat;
127             Mat=Mat*Mat;
128             n>>=1;
129         }
130         int ans=0;
131         REP(i,tot)ans+=tmp.mat[0][i];
132         ans%=MOD;
133         cout<<ans<<endl;
134 
135     }
136     return 0;
137 }
代码君
 

posted on 2015-03-14 22:51  xyiyy  阅读(263)  评论(0编辑  收藏  举报

导航