poj 2778 DNA Sequence AC自动机DP 矩阵优化
DNA Sequence
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 11860 | Accepted: 4527 |
Description
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
Next m lines each line contain a DNA genetic disease segment, and length of these segments is not larger than 10.
Output
Sample Input
4 3
AT
AC
AG
AA
Sample Output
36
几个月没编AC自动机,突然编一下感觉之痛苦。
主要问题一点是fail指针构造时没有即使break掉,另一点是tail标记上传时需要加入一个while循环。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 100
#define MAXT 100
#define MOD 100000
typedef long long qword; struct trie_node
{
int ptr[];
int fail;
char w;
bool tl;
}trie[MAXT];
int topt=;
char str[MAXN];
void Add_word(char *str)
{
int now=;
int ind;
while (*str)
{
ind=*(str++)-'A';
if (!trie[now].ptr[ind])
{
trie[now].ptr[ind]=++topt;
trie[topt].w=ind+'A';
trie[topt].tl=false;
}
now=trie[now].ptr[ind];
}
trie[now].tl=true;
}
int q[MAXN];
void Build_Ac()
{
int head=-,tail=;
int now,temp;
int i,j;
q[]=;
trie[].fail=;
while (head<tail)
{
now=q[++head];
for (i=;i<;i++)
{
if (!trie[now].ptr[i])continue;
q[++tail]=trie[now].ptr[i];
if (now==)
{
trie[trie[now].ptr[i]].fail=now;
continue;
}
temp=trie[now].fail;
while(temp!=)
{
if (trie[temp].ptr[i])
{
trie[trie[now].ptr[i]].fail=trie[temp].ptr[i];
break;
}
temp=trie[temp].fail;
}
if (!trie[trie[now].ptr[i]].fail)
trie[trie[now].ptr[i]].fail=trie[].ptr[i];
if (!trie[trie[now].ptr[i]].fail)
trie[trie[now].ptr[i]].fail=;
}
}
for (i=;i<=topt;i++)
{
for (j=;j<;j++)
{
if (!trie[i].ptr[j])
{
temp=trie[i].fail;
while (temp!=)
{
if (trie[temp].ptr[j])
{
trie[i].ptr[j]=trie[temp].ptr[j];
break;
}
temp=trie[temp].fail;
}
if (!trie[i].ptr[j])
trie[i].ptr[j]=trie[].ptr[j];
if (!trie[i].ptr[j])
trie[i].ptr[j]=;
}
}
}
j=;
while (j--)
{
for (i=;i<=tail;i++)
{
if (trie[trie[i].fail].tl)
trie[i].tl=true;
}
}
}
struct matrix
{
int n,m;
qword a[MAXN][MAXN];
matrix()
{
memset(a,,sizeof(a));
}
void pm()
{
int i,j;
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
{
printf("% 4d ",a[i][j]);
}
printf("\n");
}
printf("\n");
}
}m1,r1,m2;
matrix operator *(matrix &m1,matrix &m2)
{
if (m1.m!=m2.n)throw ;
matrix ret;
ret.n=m1.n;
ret.m=m2.m;
int i,j,k;
for (i=;i<=ret.n;i++)
{
for (j=;j<=ret.m;j++)
{
for (k=;k<=m1.m;k++)
{
ret.a[i][j]=(ret.a[i][j]+m1.a[i][k]*m2.a[k][j])%MOD;
}
}
}
return ret;
} int main()
{
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int n,m,i,j,k,x,y,z;
scanf("%d%d\n",&m,&n);
topt=;
trie[].w='#';
for (i=;i<m;i++)
{
scanf("%s",str);
x=strlen(str);
for (j=;j<x;j++)
{
switch(str[j])
{
case 'A':str[j]='A';break;
case 'G':str[j]='B';break;
case 'C':str[j]='C';break;
case 'T':str[j]='D';break;
}
}
Add_word(str);
}
Build_Ac();
m1.m=m1.n=topt;
for (i=;i<=topt;i++)
{
for (j=;j<;j++)
{
if (trie[trie[i].ptr[j]].tl)continue;
m1.a[trie[i].ptr[j]][i]++;
}
}
// m1.pm();
m2.m=,m2.n=topt;
m2.a[][]=;
while (n)
{
if (n&)
{
m2=m1*m2;
}
m1=m1*m1;
n>>=;
}
/*
for (i=1;i<=n;i++)
{
m2=m1*m2;
// m2.pm();
}*/
qword ans=;
for (i=;i<=topt;i++)
{
ans+=m2.a[i][];
ans%=MOD;
}
printf("%d\n",ans);
return ;
}
poj 2778 DNA Sequence AC自动机DP 矩阵优化的更多相关文章
- POJ 2778 DNA Sequence (AC自动机+DP+矩阵)
题意:给定一些串,然后让你构造出一个长度为 m 的串,并且不包含以上串,问你有多少个. 析:很明显,如果 m 小的话 ,直接可以用DP来解决,但是 m 太大了,我们可以认为是在AC自动机图中,根据离散 ...
- POJ 2778 DNA Sequence ( AC自动机、Trie图、矩阵快速幂、DP )
题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析 : 这题搞了我真特么久啊,首先你需要知道的前置技能包括 AC自动机.构建Trie图.矩阵快速幂,其中矩 ...
- poj 2778 DNA Sequence ac自动机+矩阵快速幂
链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...
- POJ 2778 DNA Sequence (AC自动机,矩阵乘法)
题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...
- poj 2778 DNA Sequence AC自动机
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11860 Accepted: 4527 Des ...
- POJ 2778 DNA Sequence (AC自己主动机 + dp)
DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...
- [POJ2778]DNA Sequence(AC自动机 + DP + 矩阵优化)
传送门 AC自动机加DP就不说了 注意到 m <= 10,所以模式串很少. 而 n 很大就需要 log 的算法,很容易想到矩阵. 但是该怎么构建? 还是矩阵 A(i,j) = ∑A(i,k) * ...
- POJ 3691 DNA repair(AC自动机+DP)
题目链接 能AC还是很开心的...此题没有POJ2778那么难,那个题还需要矩阵乘法,两个题有点相似的. 做题之前,把2778代码重新看了一下,回忆一下当时做题的思路,回忆AC自动机是干嘛的... 状 ...
- HDU 2457/POJ 3691 DNA repair AC自动机+DP
DNA repair Problem Description Biologists finally invent techniques of repairing DNA that contains ...
随机推荐
- [React] React Fundamentals: JSX Deep Dive
"JSX transforms from an XML-like syntax into native JavaScript. XML elements and attributes are ...
- 使用Broadcast实现android组件之间的通信 分类: android 学习笔记 2015-07-09 14:16 110人阅读 评论(0) 收藏
android组件之间的通信有多种实现方式,Broadcast就是其中一种.在activity和fragment之间的通信,broadcast用的更多本文以一个activity为例. 效果如图: 布局 ...
- Div+css中ul ol li dl dt dd使用
ol 有序列表.<ol><li>……</li><li>……</li><li>……</li></ol>表现 ...
- CentOS7系统下搭建Jenkins环境
1. 安装JDK yum -y install java 2.安装Ant 添加JPackage源 yum -y install wget wget http://www.jpackage.org/jp ...
- JS获取URL的参数
function request(paras) { var url = location.href; , url.length).split("&"); var paraO ...
- jQuery Ajax 实例 全解析
jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯. 废话少说,直接进入正题,我们先来看一些简单的方法,这些方法都是 ...
- Struts2,Hibernate和Spring之间的框架整合关系
1.首先要认清,hibernate和struts没有半点关系,所以他们之间没有任何可以整合的东西.a:struts 作为中心控制器,肯定要调用一些类来完成一些逻辑.而hibernate开发中,经常使用 ...
- sqlserver 自定义字符串分割函数.
--SQL Server Split函数 --Author: sq --说明:被分割后的字段为:short_str --支持分割符多字节 --使用方法 --Select * FROM splits(' ...
- 《你不常用的c#之三》:Action 之怪状
转载自csdn:http://blog.csdn.net/robingaoxb/article/details/6199891 例1: public static void Main() { Li ...
- web开发基础(同步更新中)
1/Get与Post的区别 GET是我们都熟悉的.它用于请求网页文本.当你在浏览器输入harvard.edu,它会直接访问Harvard的web服务器,去GET /. 第二个最有名的是POST,它经常 ...