POJ2778 DNA Sequence(AC自动机+矩阵快速幂)
题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个。
感觉这题好神,看了好久的题解。
所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个结点都可以看作是某个病毒串的前缀,Trie树的根则是空字符串。
而从根出发,在AC自动机上跑,经过k次转移到达某个结点,这个结点所代表的病毒串前缀可以看作长度为k的字符串的后缀,如果接下去跑往ATCG四个方向转移,就能到达新的结点,转移到新的长k+1字符串的后缀。
这样带着一个后缀状态的转移就能绕开病毒串,所以病毒串末尾的结点要标记,后缀存在病毒串的结点也要标记(这个在计算结点fail的时候就能处理),转移时就不能转移到被标记的结点。
接下来,题目的数据范围是10个长度10的病毒串,所以Trie树中最多101左右个结点,那么AC自动机整个转移就可以构建一张101*101的邻接矩阵,矩阵i行j列的权值是结点i转移到结点j的方案数。
而进行k次转移,从结点i转移到结点j的方案数是这个矩阵的k次幂,这个结论离散数学的图论有。。
所以,长度n的字符串的方案数,就是转移n次根结点能到所有结点的方案和就是答案。就是计算矩阵的n次幂,统计根所在行的数字和,n的达到20亿用矩阵快速幂即可。
(POJ从昨天就挂了。。SCU有原题,多组数据,http://acm.scu.edu.cn/soj/problem.action?id=3030)
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int ch[][],fail[],tn;
bool flag[]; int idx[];
void insert(char *s){
int x=;
for(int i=; s[i]; ++i){
int y=idx[s[i]];
if(ch[x][y]==) ch[x][y]=++tn;
x=ch[x][y];
}
flag[x]=;
}
void init(){
memset(fail,,sizeof(fail));
queue<int> que;
for(int i=; i<; ++i){
if(ch[][i]) que.push(ch[][i]);
}
while(!que.empty()){
int now=que.front(); que.pop();
for(int i=; i<; ++i){
if(ch[now][i]) que.push(ch[now][i]),fail[ch[now][i]]=ch[fail[now]][i];
else ch[now][i]=ch[fail[now]][i];
flag[ch[now][i]]|=flag[ch[fail[now]][i]];
}
}
}
struct Mat{
long long mat[][];
Mat(){
memset(mat,,sizeof(mat));
}
};
Mat operator*(const Mat &m1,const Mat &m2){
Mat m;
for(int i=; i<=tn; ++i){
for(int j=; j<=tn; ++j){
for(int k=; k<=tn; ++k){
m.mat[i][j]+=m1.mat[i][k]*m2.mat[k][j];
m.mat[i][j]%=;
}
}
}
return m;
}
int main(){
idx['A']=; idx['C']=; idx['T']=; idx['G']=;
char str[];
int m,n;
while(~scanf("%d%d",&m,&n)){
tn=;
memset(flag,,sizeof(flag));
memset(ch,,sizeof(ch));
while(m--){
scanf("%s",str);
insert(str);
}
init();
Mat e,x;
for(int i=; i<=tn; ++i) e.mat[i][i]=;
for(int i=; i<=tn; ++i){
if(flag[i]) continue;
for(int j=; j<; ++j){
if(flag[ch[i][j]]) continue;
++x.mat[i][ch[i][j]];
}
}
while(n){
if(n&) e=e*x;
x=x*x;
n>>=;
}
long long res=;
for(int i=; i<=tn; ++i){
res+=e.mat[][i];
res%=;
}
printf("%lld\n",res);
}
return ;
}
POJ2778 DNA Sequence(AC自动机+矩阵快速幂)的更多相关文章
- [poj2778]DNA Sequence(AC自动机+矩阵快速幂)
题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列.(仅含A,T,C,G四个字符) 解题关键: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& ...
- 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 ...
随机推荐
- web_url、web_custom_request、web_submit_data、web_submit_form的使用实例
业务:根据url获取图片用web_url()函数访问数据;请求方式:HTTP GET 请求;Action(){web_url("imageproxytest", "URL ...
- js打印(控件)及多种方式
非常好用的LODOP打印控件 Lodop打印控件简单使用方法 1.安装. 2.调用LodopFuncs.js文件. 3.增加OBJECT对象 <script language="jav ...
- Struts2配置文件模板
<?xml version = "1.0" encoding = "UTF-8"?><!--下面是Struts2配置文件的DTD信息 --&g ...
- HDOJ 1102 生成树
Constructing Roads Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- 2.11 2D平面最近点对问题[closest pair problem]
[本文链接] http://www.cnblogs.com/hellogiser/p/closest-pair-problem.html [题目] 给定平面上N个点的坐标,找出距离最近的两个点之间的距 ...
- Android Studio "diamond operator is not supported" 处理方法
低版本的android编译环境是不支持使用java7语法的,如果使用了,就会产生上述问题,如果你的android环境较新,那么可以使用以下方法: 在build.gradle的android标签下加入以 ...
- Java for LeetCode 145 Binary Tree Postorder Traversal
Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary ...
- Lubuntu下配置Python开发环境
安装完系统必须要做的几件事: 一.更新软件 (如果是通过最新版镜像安装,可无视此步骤) 1.选择速度比较快的源,默认的源速度不一定快.二.配置终端 1.设置终端背景,前景色,透明度 ...
- Gym 100801D Distribution in Metagonia (数学思维题)
题目:传送门.(需要下载PDF) 题意:t组数据,每组数据给定一个数ni(1 ≤ ni ≤ 10^18),把ni拆成尽可能多的数,要求每个数的素因子只包含2和3,且这些数不能被彼此整除,输出一共能拆成 ...
- [MAC ] Mac-OSX下安装Git
转载自 : http://www.cnblogs.com/shanyou/archive/2011/01/30/1948088.html Mac-OSX下安装Git是一件很简单的事,我们可以下载一个安 ...