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 }
代码君
 

你可能感兴趣的:(sequence)