[poj2778]DNA Sequence(AC自动机+矩阵快速幂)
题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列。(仅含A,T,C,G四个字符)
解题关键:AC自动机,实际上就是一个状态转移图,注意能少取模就少取模,尤其是在快速幂的时候,消耗时间极其巨大,此题效率差10倍。
先+=在进行取模,两者分开,也可以快1倍。
按照AC自动机建立邻接矩阵,其中不含病毒模式串的位置可以到达,

其中上图矩阵为:
2 1 0 0 1
2 1 1 0 0
1 1 0 1 1
2 1 0 0 1
2 1 0 0 1
去掉病毒结点之后,变为
2 1
2 1
转移方程:$dp[u] = \sum\limits_{v - > u} {dp[v]} $
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
const int N=;
const int MAXN=;
struct mat{
ll m[][];
};
ll m,n;
ll mod=;
struct Trie{
int Next[MAXN][N],Fail[MAXN],root,tot;
bool End[MAXN];
int newnode(){
for(int i=;i<N;i++) Next[tot][i]=-;
End[tot++]=false;
return tot-;
}
void init(){
tot=;
root=newnode();
}
void insert(char buf[]){
int len=strlen(buf),now=root,k;
for(int i=;i<len;i++){
if(buf[i]=='A') k=;
else if(buf[i]=='G') k=;
else if(buf[i]=='C') k=;
else k=;
if(Next[now][k]==-) Next[now][k]=newnode();
now=Next[now][k];
}
End[now]=true;
}
void build(){
queue<int>que;
Fail[root]=root;
for(int i=;i<N;i++){
if(Next[root][i]==-) Next[root][i]=root;
else{
Fail[Next[root][i]]=root;
que.push(Next[root][i]);
}
}
while(!que.empty()){
int now=que.front();
que.pop();
if(End[Fail[now]]) End[now]=true;
for(int i=;i<N;i++){
if(Next[now][i]==-) Next[now][i]=Next[Fail[now]][i];
else{
Fail[Next[now][i]]=Next[Fail[now]][i];
que.push(Next[now][i]);
}
}
}
}
mat get_mat(int len){
mat B={};
for(int i=;i<len;i++){
for(int j=;j<N;j++){
if(End[Next[i][j]]==false) B.m[i][Next[i][j]]++;//不能直接置1
}
}
return B;
}
}; mat mul(mat &A,mat &B,int len){
mat C={};
for(int i=;i<len;i++){
for(int j=;j<len;j++){
for(int k=;k<len;k++){
C.m[i][j]+=A.m[i][k]*B.m[k][j];
}
C.m[i][j]%=mod;
}
}
return C;
} mat pow(mat A,ll n,int len){
mat B={};
for(int i=;i<len;i++) B.m[i][i]=;
while(n){
if(n&) B=mul(B,A,len);
A=mul(A,A,len);
n>>=;
}
return B;
} Trie ac;
char buf[];
int main(){
while(scanf("%lld%lld",&m,&n)!=EOF){
ac.init();
for(int i=;i<m;i++){
scanf("%s",buf);
ac.insert(buf);
}
ac.build();
mat B=ac.get_mat(ac.tot);
B=pow(B,n,ac.tot);
ll res=;
for(int i=;i<ac.tot;i++){
res+=B.m[][i];
}
printf("%lld\n",res%mod);
}
return ;
}
[poj2778]DNA Sequence(AC自动机+矩阵快速幂)的更多相关文章
- poj2778 DNA Sequence(AC自动机+矩阵快速幂)
Description It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's ve ...
- poj 2778 DNA Sequence ac自动机+矩阵快速幂
链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...
- poj2778DNA Sequence (AC自动机+矩阵快速幂)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud DNA Sequence Time Limit: 1000MS Memory ...
- POJ2778 DNA Sequence(AC自动机 矩阵)
先使用AC自动机求得状态转移关系,再建立矩阵,mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数,则此矩阵的n次方表示n步从i,到j的方法数. #include<cstdio& ...
- POJ2778 DNA Sequence(AC自动机+矩阵快速幂)
题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个 ...
- POJ 2778 DNA Sequence (ac自动机+矩阵快速幂)
DNA Sequence Description It's well known that DNA Sequence is a sequence only contains A, C, T and G ...
- DNA Sequence POJ - 2778 AC自动机 && 矩阵快速幂
It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to ...
- POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解
题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...
- POJ2778(SummerTrainingDay10-B AC自动机+矩阵快速幂)
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17160 Accepted: 6616 Des ...
随机推荐
- c# vitural
virtual关键字用于指定属性或方法在派生类中重写. 默认情况下,派生类类从其基类继承属性和方法,如果继承的属性或方法需要在派生类中有不同的行为,则可以重写它,即可以在派生类中定义该属性或方法的新实 ...
- 我的跟我学Ffmpeg 视频受众有哪些人
经常有人问我如何学习音视频以及如何学习Ffmpeg,问我有没有比较好的书的书推荐.比较好的音视频以及FFmpeg方面的 书,我了解到的比较全面又能深入浅出的还真没有.很多朋友都推荐雷神的博客,雷神的博 ...
- Crtmp Server 几个关键流程
最近在阅读Crtmp Sever 源码,有些关键流程记录下来,以备以后查阅.假设rtmp播放地址是"rtmp://127.0.0.1/live/mystream live=1" 1 ...
- 算法排序-lowB三人组
冒泡排序思路: 选择排序思路: 插入排序思路: 小结: 详细代码解释看下一篇
- JSP 随记
jstl <c:forEach> 遍历,多个<option>时显示"全部".单个 option时,默认选中! 引入:<%@ taglib prefix ...
- Ubuntu NDK配置与JNI demo
NDK配置 1.下载最新版本NDK(android-ndk-r9d-linux-x86_64.tar.bz2) 下载网页:http://developer.android.com/tools/sdk/ ...
- javaScript中innerHTML,innerText,outerHTML,outerText的区别
开头说下innerText和outerText只在chrome浏览器中有效 定义和用法 innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML,包括标签. 来看代码 <!DOC ...
- apktool + eclipse 动态调试APK
用了会AndBug,尽管挺强大的可是作为习惯了OD.EDB作为动态调试工具的人,自然有些不习惯,于是乎寻求新的动态调试解决方式.但大多数都是NetBeans + apktool.想着还得多下一个IDE ...
- 在Windows平台用visual studio编译的可执行文件部署时报:应用程序无法正常启动0xc000007b(跟DirectX9无关的原因)
最近在做EasyDarwin开源流媒体服务器Windows版本编译与部署时发现一个问题,在开发机本机运行都很正常,但是部署到目标机器(未安装vs等开发环境)时,莫名其妙报出了"应用程序无法正 ...
- EasyRTMP实现的rtmp推流的基本协议流程
EasyRTMP介绍 EasyRTMP是结合了多种音视频缓存及网络技术的一个rtmp直播推流端,包括:圆形缓冲区(circular buffer).智能丢帧.自动重连.rtmp协议等等多种技术,能够非 ...