线性代数(矩阵乘法):POJ 2778 DNA Sequence
DNA Sequence
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
思路是这样的:把所有病毒片段放入AC自动机中,建立fail数组。如果一个状态的fail为病毒节点,则他自己也为病毒节点。最后按边建矩阵,快速幂。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 using namespace std; 6 const int maxn=110; 7 const int mod=100000; 8 typedef unsigned long long ull; 9 struct Matrix{ 10 int n; 11 ull mat[maxn][maxn]; 12 Matrix(int n_,int on=0){ 13 n=n_;memset(mat,0,sizeof(mat)); 14 if(on)for(int i=1;i<=n;i++)mat[i][i]=1; 15 } 16 Matrix operator *(Matrix a){ 17 Matrix ret(n); 18 unsigned long long l; 19 for(int i=1;i<=n;i++) 20 for(int k=1;k<=n;k++){ 21 l=mat[i][k]; 22 for(int j=1;j<=n;j++) 23 (ret.mat[i][j]+=l*a.mat[k][j]%mod)%=mod; 24 } 25 return ret; 26 } 27 Matrix operator ^(long long k){ 28 Matrix ret(n,1); 29 while(k){ 30 if(k&1) 31 ret=ret**this; 32 k>>=1; 33 *this=*this**this; 34 } 35 return ret; 36 } 37 }; 38 39 struct AC_automation{ 40 bool tag[maxn]; 41 int cnt,rt,ch[maxn][4],fail[maxn]; 42 AC_automation(){ 43 memset(tag,0,sizeof(tag)); 44 memset(fail,0,sizeof(fail)); 45 memset(ch,0,sizeof(ch));cnt=rt=1; 46 } 47 48 int ID(char c){ 49 if(c=='A')return 0; 50 else if(c=='C')return 1; 51 else if(c=='G')return 2; 52 else return 3; 53 } 54 55 void Insert(char *s){ 56 int len=strlen(s),p=rt; 57 for(int i=0;i<len;i++) 58 if(ch[p][ID(s[i])]) 59 p=ch[p][ID(s[i])]; 60 else 61 p=ch[p][ID(s[i])]=++cnt; 62 tag[p]=true; 63 } 64 65 void Build(){ 66 queue<int>q; 67 for(int i=0;i<4;i++) 68 if(ch[rt][i]) 69 fail[ch[rt][i]]=rt,q.push(ch[rt][i]); 70 else 71 ch[rt][i]=rt; 72 73 while(!q.empty()){ 74 int x=q.front();q.pop(); 75 for(int i=0;i<4;i++) 76 if(ch[x][i]){ 77 fail[ch[x][i]]=ch[fail[x]][i]; 78 tag[ch[x][i]]|=tag[fail[ch[x][i]]]; 79 q.push(ch[x][i]); 80 } 81 else 82 ch[x][i]=ch[fail[x]][i]; 83 } 84 } 85 86 void Solve(int k){ 87 Matrix A(cnt); 88 for(int i=1;i<=cnt;i++) 89 for(int j=0;j<4;j++) 90 if(!tag[i]&&!tag[ch[i][j]]) 91 A.mat[ch[i][j]][i]+=1; 92 A=A^k; 93 long long ans=0; 94 for(int i=1;i<=cnt;i++) 95 ans+=A.mat[i][1]; 96 printf("%lld\n",ans%mod); 97 } 98 }ac; 99 char s[maxn]; 100 101 int main(){ 102 #ifndef ONLINE_JUDGE 103 //freopen("","r",stdin); 104 //freopen("","w",stdout); 105 #endif 106 int tot,n; 107 scanf("%d%d",&tot,&n); 108 while(tot--){ 109 scanf("%s",s); 110 ac.Insert(s); 111 } 112 ac.Build(); 113 ac.Solve(n); 114 return 0; 115 }
尽最大的努力,做最好的自己!