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.
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.
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自动机得出一个邻接矩阵,然后快速幂。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }