POJ 2778 DNA Sequence(自动机+矩阵)
2015-04-22 00:25
357 查看
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
Sample Output
36
先考虑一个简单的问题。
有向图,从i->j走n步的不同方法。构造矩阵,n次幂就是答案。
回到本题。自动机本身就是个有向图。那么去掉危险节点的n次幂
就是走构造长度为n的字符串的方法。
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
先考虑一个简单的问题。
有向图,从i->j走n步的不同方法。构造矩阵,n次幂就是答案。
回到本题。自动机本身就是个有向图。那么去掉危险节点的n次幂
就是走构造长度为n的字符串的方法。
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<bitset> using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) typedef long long LL; typedef pair<int,int>pil; const int INF = 0x3f3f3f3f; const int maxn=5500; const int MOD=1e5; int n,m,L; int ed[maxn]; int next[maxn][26]; int fail[maxn]; struct Matrix{ LL mat[110][110]; void Clear() { CLEAR(mat,0); } }; struct AC{ int root; int newnode() { for (int i = 0; i < 4; ++i) next[L][i] = -1; ed[L++] = 0; return L - 1; } void init() { L = 0; root = newnode(); } int ID(char c) { if (c == 'A') return 0; if (c == 'G') return 1; if (c == 'C') return 2; if (c == 'T') return 3; } void Insert(char buf[]) { int now = root; int len = strlen(buf); for (int i = 0; i < len; ++i) { if (next[now][ID(buf[i])] == -1) next[now][ID(buf[i])] = newnode(); now = next[now][ID(buf[i])]; } ed[now] = 1; } void Build_AC() { queue<int>q; fail[root]=root; for(int i=0;i<4;i++) { if(next[root][i]==-1) next[root][i]=root; else { fail[next[root][i]]=root; q.push(next[root][i]); } } while(!q.empty()) { int now=q.front(); q.pop(); if(ed[fail[now]]) ed[now]=1; for(int i=0;i<4;i++) { if(next[now][i]==-1) next[now][i]=next[fail[now]][i]; else { fail[next[now][i]]=next[fail[now]][i]; q.push(next[now][i]); } } } } }; Matrix mult(Matrix m1,Matrix m2) { Matrix ans; for(int i=0;i<L;i++) { for(int j=0;j<L;j++) { ans.mat[i][j]=0; for(int k=0;k<L;k++) ans.mat[i][j]=(ans.mat[i][j]+m1.mat[i][k]*m2.mat[k][j])%MOD; } } return ans; } Matrix Pow(Matrix m1,LL b) { Matrix ans;ans.Clear(); for(int i=0;i<L;i++) ans.mat[i][i]=1; while(b) { if(b&1) ans=mult(ans,m1); b>>=1; m1=mult(m1,m1); } return ans; } void work() { Matrix ans; for(int i=0;i<L;i++) { if(ed[i]) continue; for(int j=0;j<4;j++) { if(ed[next[i][j]]) continue; ans.mat[i][next[i][j]]++; } } ans=Pow(ans,m); LL sum=0; for(int i=0;i<L;i++) { if(!ed[i]) { sum+=ans.mat[0][i]; sum%=MOD; } } printf("%lld\n",sum); } AC A; int main() { char str[15]; while(~scanf("%d%d",&n,&m)) { A.init(); REPF(i,1,n) { scanf("%s",str); A.Insert(str); } A.Build_AC(); work(); } return 0; }
相关文章推荐
- POJ 2778 DNA Sequence(自动机+矩阵DP)
- POJ 2778 DNA Sequence (AC 自动机+矩阵)
- POJ 2778 DNA Sequence (AC自动机+矩阵加速,4级)
- POJ 2778 DNA Sequence (AC自动机+矩阵加速,4级)
- POJ 2778 DNA Sequence (自动机DP+矩阵快速幂)
- POJ 2778 DNA Sequence(AC自动机确定DFA转移图+矩阵快速幂)
- POJ 2778 - DNA Sequence (AC自动机 矩阵快速幂)
- poj 2778 DNA Sequence 【AC自动机 + 矩阵加速】
- POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]
- POJ 2778 DNA Sequence (AC自动机+DP+矩阵)
- POJ2778 DNA sequence[自动AC机&矩阵快速幂]
- POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]
- POJ 2778 DNA Sequence && AC自动机 矩阵 矩阵加速
- POJ 2778 DNA Sequence (AC自动机 + 矩阵快速幂)
- POJ 2778 DNA Sequence (AC自动机)
- poj -- 2778 DNA Sequence && hdu -- 2243 考研路茫茫——单词情结(AC自动机 + 矩阵)
- POJ 2778 DNA Sequence (AC自动机,矩阵乘法)
- [POJ 2778] DNA Sequence (AC自动机+DP+矩阵加速)
- poj2778.DNA Sequence (Trie图 && 矩阵乘)
- 线性代数(矩阵乘法):POJ 2778 DNA Sequence