poj 2778 DNA Sequence ac自动机+矩阵快速幂
2016-05-09 17:47
459 查看
http://poj.org/problem?id=2778
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.
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
问题大意:长度为n 由’A’‘G’‘C’‘T‘组成的字符串中不包含这m个字符串的任意一个的组合有多少种;
标记每个字符串的结尾节点为危险节点,如果失败后跳转到的节点是危险节点那么该节点也应为危险节点。
问题转化为长度问n不经过危险节点的走法有多少种。
构造矩阵mat,mat[i][j]为从第i个节点走一步到达第j个节点有多少种走法。求下mat的n次方,即求得ans[][],ans[i][j]为第i个节点走n步到达第j个节点的走法有多少种。
求下ans[0][i]的和就好。
理解好ac自动机和矩阵的含义后还是很好理解的。
后台数据比题意的数据要大一些。一开始一直wa,改了范围就A了。
DNA Sequence
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 14470 | Accepted: 5579 |
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
问题大意:长度为n 由’A’‘G’‘C’‘T‘组成的字符串中不包含这m个字符串的任意一个的组合有多少种;
标记每个字符串的结尾节点为危险节点,如果失败后跳转到的节点是危险节点那么该节点也应为危险节点。
问题转化为长度问n不经过危险节点的走法有多少种。
构造矩阵mat,mat[i][j]为从第i个节点走一步到达第j个节点有多少种走法。求下mat的n次方,即求得ans[][],ans[i][j]为第i个节点走n步到达第j个节点的走法有多少种。
求下ans[0][i]的和就好。
理解好ac自动机和矩阵的含义后还是很好理解的。
后台数据比题意的数据要大一些。一开始一直wa,改了范围就A了。
#include <cstdio> #include <cstdio> #include <cstring> #include <cctype> #include <cmath> #include <set> #include <map> #include <list> #include <queue> #include <deque> #include <stack> #include <string> #include <bitset> #include <vector> #include <iostream> #include <algorithm> #define maxx(a,b) ((a)>(b)?(a):(b)) #define F first #define S second using namespace std; typedef long long LL; typedef unsigned long long uLL; const int mod = 100000; const LL inf=0x3f3f3f3f; //const double pi=acos(-1); const int N=210;//最大点数 const int M=130;// 最大边数 int ans; int bl[500]; struct mat { int v[210][210]; }; mat c,an; int size_mat; mat matrix_mul(mat p1,mat p2,int n,int m,int q) { mat t; memset(t.v,0,sizeof(t.v)); for(int i=0; i<n; i++) for(int j=0; j<m; j++) if(p1.v[i][j]) for(int k=0; k<q; k++) { int tep=((long long )p1.v[i][j]*p2.v[j][k])%mod; t.v[i][k]=(t.v[i][k]+tep)%mod; } return t; } mat matrix_mi(mat p,int n,int k) { mat t; memset(t.v,0,sizeof(t.v)); for(int i=0; i<n; i++) { t.v[i][i]=1; } while(k) { if(k&1) t=matrix_mul(t,p,n,n,n); k>>=1; p=matrix_mul(p,p,n,n,n); } return t; } struct Trie { int next [4],fail ,end ; int root,L; int nownode() { for(int i=0; i<4; i++) next[L][i]=-1; end[L++]=0; return L-1; } void init() { L=0; root=nownode(); } void insert(char buf[],int k) { int len=strlen(buf); int now=root; for(int i=0; i<len; i++) { if(next[now][bl[buf[i]]]==-1) next[now][bl[buf[i]]]=nownode(); now=next[now][bl[buf[i]]]; } end[now]=1; } void build() { 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(end[fail[now]]==1) end[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]); } } } } int gett() { for(int i=0; i<L; i++) { for(int j=0; j<4; j++) { if(end[next[i][j]]==0) c.v[i][next[i][j]]++; } } return L; } }; Trie ac; char str[500]; int main() { #ifdef LOCAL freopen("date.in","r",stdin); freopen("date.out","w",stdout); #endif int m,n; bl['A']=0; bl['G']=1; bl['C']=2; bl['T']=3; while(scanf("%d%d",&m,&n)!=EOF) { ac.init(); for(int i=1; i<=m; i++) { scanf("%s",str); ac.insert(str,i); } ac.build(); memset(c.v,0,sizeof(c.v)); size_mat=ac.gett(); an=matrix_mi(c,size_mat,n); ans=0; // for(int i=0;i<size_mat;i++) // { // puts(""); // for(int j=0;j<size_mat;j++) // printf("%d ",an.v[i][j]); // } for(int i=0;i<size_mat;i++) { ans+=an.v[0][i]; ans%=mod; } printf("%d\n",ans); } return 0; }
相关文章推荐
- iOS UISegmentedControl设置指定索引选项不可选
- Web Service单元测试工具实例介绍之SoapUI
- iOS UIAlertController的使用
- [iOS-UI]给输入框添加清除按钮的代码
- 百度编辑器UEditor常用设置函数大全
- error: lvalue required as unary ‘&’ operand
- VS2013error MSB8031: Building an MFC project for a non-Unicode character set is deprecated. You must
- ios 设置UITextField的placeholder大小颜色
- UIButton文字居左显示
- 【Arduino官方教程第一辑】示例程序 3-3 模拟信号输出[Mega]
- UI之登录界面
- mysql Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT
- 187. Repeated DNA Sequences
- 布局+基本UI
- JS 生成GUID 方法
- UILabel设置行间距
- javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available..
- iOS UIImageView 的使用
- 187. Repeated DNA Sequences 【M】【30】
- iOS 自定义UIButton的title和image位置