poj2778 DNA Sequence【AC自动机】【矩阵快速幂】
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 19991 | Accepted: 7603 |
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个致病基因序列。问长度为n的DNA序列中有多少个是没有这些序列的。
思路:
这道题用到AC自动机的状态转移的性质了。
当我建好了状态图之后,在某一个状态a时,我可以知道他可以到达的所有状态。Trie树上的一个节点就是一个状态。
初始矩阵mat[i][j]表示的是从状态i走一步到状态j有几种可能。使用矩阵快速幂,对这个矩阵做n次幂,就可以得到每个两个状态之间走n次总共有多少方案。
对于一个长为n的串,没有任何一个致病基因序列,那么所有致病基因转移过去的状态都不能算进去。
我们给每一个致病基因做一个危险标记,同时要注意所有fail可以到达的节点如果是danger的,他自己也要变成danger
因为这段致病基因作为后缀出现在这个串中了。
#include <iostream>
#include <set>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
//#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define inf 0x7f7f7f7f int m, n;
const int maxn = ;
const int maxlen = 2e6 + ; struct Matrix
{
unsigned long long mat[][];
int n;
Matrix(){}
Matrix(int _n)
{
n=_n;
for(int i=;i<n;i++)
for(int j=;j<n;j++)
mat[i][j] = ;
}
Matrix operator *(const Matrix &b)const
{
Matrix ret = Matrix(n);
for(int i=;i<n;i++)
for(int j=;j<n;j++)
for(int k=;k<n;k++)
ret.mat[i][j]+=mat[i][k]*b.mat[k][j] % ;
return ret;
}
void print()
{
for(int i = ; i < n; i++){
for(int j = ; j < n; j++){
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
}; unsigned long long pow_m(unsigned long long a, int n)
{
unsigned long long ret = ;
unsigned long long tmp = a;
while(n){
if(n & )ret *= tmp;
tmp *= tmp;
n >>= ;
}
return ret;
} Matrix pow_M(Matrix a, int n)
{
Matrix ret = Matrix(a.n);
for(int i = ; i < a.n; i++){
ret.mat[i][i] = ;
}
Matrix tmp = a;
//cout<<a.n<<endl;
while(n){
if(n & )ret = ret * tmp;
tmp = tmp * tmp;
n >>= ;
//ret.print();
//cout<<endl;
}
return ret;
} struct tree{
int fail;
int son[];
bool danger;
}AC[maxlen];
int tot = , id[];
char s[]; void build(char s[])
{
int len = strlen(s);
int now = ;
for(int i = ; i < len; i++){
int x = id[s[i]];
if(AC[now].son[x] == ){
AC[now].son[x] = ++tot;
}
now = AC[now].son[x];
}
AC[now].danger = true;
} void get_fail()
{
queue<int>que;
for(int i = ; i < ; i++){
if(AC[].son[i] != ){
AC[AC[].son[i]].fail = ;
que.push(AC[].son[i]);
}
}
while(!que.empty()){
int u = que.front();
que.pop();
for(int i = ; i < ; i++){
if(AC[u].son[i] != ){
AC[AC[u].son[i]].fail = AC[AC[u].fail].son[i];
que.push(AC[u].son[i]);
}
else{
AC[u].son[i] = AC[AC[u].fail].son[i];
}
int x = AC[AC[u].son[i]].fail;
if(AC[x].danger){
AC[AC[u].son[i]].danger = true;
}
}
}
} /*int AC_query(char s[])
{
int len = strlen(s);
int now = 0, cnt = 0;
for(int i = 0; i < len; i++){
int x = id[s[i]];
now = AC[now].son[x];
for(int t = now; t; t = AC[t].fail){
if(!AC[t].vis && AC[t].ed != 0){
cnt++;
AC[t].vis = true;
}
}
}
return cnt;
}*/ Matrix getMatrix()
{
Matrix ret = Matrix(tot + );
//int now = 0;
for(int i = ; i < tot + ; i++){
if(AC[i].danger)continue;
for(int j = ; j < ; j++){
if(AC[AC[i].son[j]].danger == false){
ret.mat[i][AC[i].son[j]]++;
}
}
}
for(int i = ; i < tot + ; i++){
ret.mat[i][tot] = ;
}
return ret;
} int main()
{
id['A'] = ;id['T'] = ;id['C'] = ;id['G'] = ;
//cout<<1<<endl;
while(~scanf("%d%d", &m, &n)){
for(int i = ; i <= tot; i++){
AC[i].fail = ;
AC[i].danger = false;
for(int j = ; j < ; j++){
AC[i].son[j] = ;
}
}
tot = ;
for(int i = ; i <= m; i++){
scanf("%s", s);
build(s);
}
AC[].fail = ;
get_fail();
Matrix mmm = Matrix(tot + );
//int now = 0;
for(int i = ; i < tot + ; i++){
if(AC[i].danger)continue;
for(int j = ; j < ; j++){
if(AC[AC[i].son[j]].danger == false){
mmm.mat[i][AC[i].son[j]]++;
}
}
} mmm = pow_M(mmm, n);
unsigned long long res = ;
for(int i = ; i < mmm.n; i++){
res = (res + mmm.mat[][i]) % ;
} printf("%lld\n", res);
}
//getchar();
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& ...
- 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 ...
随机推荐
- ARC简介以及工程中ARC与非ARC的混合(转)
ARC与非ARC在一个项目中同时使用, 1,选择项目中的Targets,选中你所要操作的Target,2,选Build Phases,在其中Complie Sources中选择需要ARC的文件双击,并 ...
- SpringBoot------使用Fastjson解析Json数据
方法一: 1.在pom.xml文件下添加依赖包 <dependency> <groupId>com.alibaba</groupId> <artifactId ...
- Java虚拟机(一):JVM内存结构
所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢?其实如果你经常解决服务器性能问题,那么这些问 ...
- Git Step by Step – (3) Git对象模型
前面一篇文章介绍了本地仓库的一系列操作,下面我们将进一步了解Git的工作原理,介绍Git对象模型. 刚开始使用Git的时候,对Git对象模型.工作原理并不理解,但是经过一段时间的使用.熟悉之后,然后再 ...
- 如何在windows上测试iphone?
本教程将会让你没有mac照样测试iphone,这是我折腾了几天总结下来的,希望对大家有用. 先来几张效果图吧 方法很简单,但是配置起来说实话有点麻烦,先在电脑上安装vmware,在安装osx系统,在安 ...
- Splash Lua 脚本
Splash 可以通过 Lua 脚本执行一系列渲染操作,这样我们就可以用 Splash 来模拟浏览器的操作了,Splash Lua 基础语法如下: function main(splash, args ...
- 深入浅出MFC——消息映射与命令传递(六)
1. 消息分类: 2. 万流归宗——Command Target(CCmdTarget): 3. "消息映射"是MFC内建的一个信息分派机制.通过三个宏(DECLARE_MESSA ...
- 【.netcore基础】MVC制器Controller依赖注入
废话少说,直接上代码 首先我们得有一个接口类和一个实现类,方便后面注入MVC里 接口类 public interface IWeatherProvider { List<WeatherForec ...
- boost::noncopyable介绍
http://blog.csdn.net/huang_xw/article/details/8248960# boost::noncopyable比较简单, 主要用于单例的情况.通常情况下, 要写一个 ...
- 游戏服务器学习笔记 5———— twisted Perspective Broker 透明代理
实际上这章压根不需要我来说,twisted官网的Doc里面有专门介绍的章节.写的非常详细. http://twistedmatrix.com/documents/current/core/howto/ ...