標籤:
轉載請註明出處: 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 3ATACAGAA
Sample Output
36
Source
POJ Monthly--2006.03.26,dodo 題意構造一個長度為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 }代碼君
poj2778DNA Sequence (AC自動機+矩陣快速冪)