POJ2278 DNA Sequence —— AC自动机 + 矩阵优化
题目链接:https://vjudge.net/problem/POJ-2778
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 18479 | Accepted: 7112 |
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
Source
题意:
给出m个DNA序列,问长度为n且不含这m个序列的DNA有多少个?
题解:
1.把这m个序列插入到AC自动机中。
2.根据自动机中各个状态之间的关系,构成一张邻接矩阵A,但需要去除与“结束点”有关的边,这样就能保证不含有给出的序列。
3.长度为n,那么答案就是 A^n 中,初始状态那一行之和。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e5;
const int MAXN = +; int Size;
int Map[];
struct MA
{
int mat[][];
void init()
{
for(int i = ; i<Size; i++)
for(int j = ; j<Size; j++)
mat[i][j] = (i==j);
}
}; MA operator*(const MA &x, const MA &y)
{
MA ret;
memset(ret.mat, , sizeof(ret.mat));
for(int i = ; i<Size; i++)
for(int j = ; j<Size; j++)
for(int k = ; k<Size; k++)
ret.mat[i][j] += (1LL*x.mat[i][k]*y.mat[k][j])%MOD, ret.mat[i][j] %= MOD;
return ret;
} MA qpow(MA x, int y)
{
MA s;
s.init();
while(y)
{
if(y&) s = s*x;
x = x*x;
y >>= ;
}
return s;
} struct Trie
{
const static int sz = , base = 'A';
int next[MAXN][sz], fail[MAXN], end[MAXN];
int root, L;
int newnode()
{
for(int i = ; i<sz; i++)
next[L][i] = -;
end[L++] = false;
return L-;
}
void init()
{
L = ;
root = newnode();
}
void insert(char buf[])
{
int len = strlen(buf);
int now = root;
for(int i = ; i<len; i++)
{
if(next[now][Map[buf[i]]] == -) next[now][Map[buf[i]]] = newnode();
now = next[now][Map[buf[i]]];
}
end[now] = true;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = ; i<sz; i++)
{
if(next[root][i] == -) next[root][i] = root;
else fail[next[root][i]] = root, Q.push(next[root][i]);
}
while(!Q.empty())
{
int now = Q.front();
Q.pop();
end[now] |= end[fail[now]]; //当前串的后缀是否也包含单词
for(int i = ; i<sz; i++)
{
if(next[now][i] == -) next[now][i] = next[fail[now]][i];
else fail[next[now][i]] = next[fail[now]][i], Q.push(next[now][i]);
}
}
} int query(int n)
{
MA s;
memset(s.mat, , sizeof(s.mat));
for(int i = ; i<L; i++)
{
if(end[i]) continue; //存在单词的状态没有后继
for(int j = ; j<sz; j++)
{
if(end[next[i][j]]) continue; //存在单词的状态没有前驱
s.mat[i][next[i][j]]++; // i到next[i][j]的路径数+1。注意,当next[i][j]==root时,路径数很可能大于1。
}
} int ret = ;
Size = L;
s = qpow(s, n);
for(int i = ; i<L; i++) //答案为:初始状态到各个状态(包括初始状态)的路径数之和。
ret = (ret+s.mat[][i])%MOD;
return ret;
}
}; Trie ac;
char buf[];
int main()
{
Map['A'] = ; Map['C'] = ; Map['G'] = ; Map['T'] = ; //离散化
int n, m;
while(scanf("%d%d", &m,&n)!=EOF)
{
ac.init();
for(int i = ; i<=m; i++)
{
scanf("%s", buf);
ac.insert(buf);
}
ac.build();
int ans = ac.query(n);
printf("%d\n", ans);
}
return ;
}
POJ2278 DNA Sequence —— AC自动机 + 矩阵优化的更多相关文章
- poj 2778 DNA Sequence ac自动机+矩阵快速幂
链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...
- [poj2778]DNA Sequence(AC自动机+矩阵快速幂)
题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列.(仅含A,T,C,G四个字符) 解题关键:AC自动机,实际上就是一个状态转移图,注意能少取模就少取模, ...
- POJ2778 DNA Sequence(AC自动机 矩阵)
先使用AC自动机求得状态转移关系,再建立矩阵,mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数,则此矩阵的n次方表示n步从i,到j的方法数. #include<cstdio& ...
- POJ 2778 DNA Sequence (AC自动机,矩阵乘法)
题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...
- 【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)
已经128天了?怎么觉得上次倒计时150天的日子还很近啊 ....好吧为了把AC自动机搞透我也是蛮拼的..把1030和这道题对比了无数遍...最终结论是...无视时间复杂度,1030可以用这种写法解. ...
- 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自动机DP 矩阵优化
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11860 Accepted: 4527 Des ...
- POJ 2778 DNA Sequence ( AC自动机、Trie图、矩阵快速幂、DP )
题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析 : 这题搞了我真特么久啊,首先你需要知道的前置技能包括 AC自动机.构建Trie图.矩阵快速幂,其中矩 ...
- [poj2778 DNA Sequence]AC自动机,矩阵快速幂
题意:给一些字符串的集合S和整数n,求满足 长度为n 只含charset = {'A'.'T‘.'G'.'C'}包含的字符 不包含S中任一字符串 的字符串的种类数. 思路:首先对S建立ac自动机,考虑 ...
随机推荐
- 简单实现接口自动化测试(基于python+unittest)
简单实现接口自动化测试(基于python+unittest) 简介 本文通过从Postman获取基本的接口测试Code简单的接口测试入手,一步步调整优化接口调用,以及增加基本的结果判断,讲解Pytho ...
- 利用Acunetix WVS进行批量网站漏洞评估
我们知道Acunetix WVS可以对网站进行安全性评估,那么怎么能批量扫描呢?游侠(www.youxia.org)在测试WVS 8 BETA2的时候发现WVS居然支持WEB管理,还是很方便的. 打开 ...
- 使用聚合数据的接口进行的RxAndroid学习
Demo数据源是聚合数据的免费Api,地址:https://www.juhe.cn/ 配合Retrofit 完成数据请求 例子比较简单,没事使用什么复杂的操作符. 就是简单的网络数据获取. 一些常用的 ...
- TCP/IP详解 卷一(第四、五章 ARP、RARP)
数据链路如 以太网都有自己的寻址机制(MAC)地址,而IP层使用的是IP地址. 当一台主机把以太网数据发送定位于同一局域网上的另一台主机时,是根据MAC地址来确定目的接口的.设备驱动程序从不检查IP数 ...
- bigAutocomplete实现联想
直接举例说明: //xx联想 var list = $(".js-xxxx").text();//需要联想出的内容的list,该list由后台传入,保存在jsp页面,js取隐藏域值 ...
- SQL CASE WHEN ... THEN ... ELSE.. END 实例
用一个SQL语句完成不同条件的分组(SELECT部分): select QuoteOrderId,SUM(case when(ApprovalStatus=1)then Amount else 0 e ...
- 14:质数因子PrimeNum
14:题目描述 功能:输入一个正整数,按照从小到大的顺序输出它的所有质数的因子(如180的质数因子为2 2 3 3 5 ) 详细描述: 函数接口说明: public String getResult( ...
- React Native 入门篇
React Native 英文官网:https://facebook.github.io/react-native/ React Native 中文官网:http://reactnative.cn/ ...
- centos部署Python环境
在centos上部署Python之前,我们需要先配置开发环境. 1.安装Python依赖的开发工具包 gcc自然少不了,可以直接用“Development Tools”: yum grouplist ...
- Mac中遇到的Eclipse连接不上mySql的问题
1.首先我们在eclipse中连接数据库的过程中,遇到的问题就是如上图.开始百度Communications link failure 这几个关键字.得到的结果基本上就是基本配置参数wait_time ...