距离上次做AC自动机有很久了=。=,以前这题的思路死活看不懂,现在还是觉得很好理解的。

  思路参见:http://blog.csdn.net/morgan_xww/article/details/7834801#

  我用cnt=1表示这个节点是危险的,然后再匹配fail指针的时候,如果一个节点的前缀是危险的,那么这个节点也是危险的,这么维护即可。

  顺便一提,我以前的AC自动机模板是没有build过程中失配时的nxt指针的(以前是在match的过程中体现),但是失败时候需要的nxt指针又是很好用的,因此以后的模板中在build中新增这个内容(其实上次的AC自动机DP中就已经有了)。

  另外两点可能不是很重要的是:1.我的矩阵模板统一是从1开始的,而这里有0节点;2.在结构体内似乎不能直接初始化字符串= =。

  代码如下(我的代码跑的有点慢。。):

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
const int MAX_Tot = + ;
const int mod = ; int m,n; void add(int &a,int b)
{
a += b;
if(a < ) a += mod;
a %= mod;
} struct matrix
{
int e[MAX_Tot][MAX_Tot],n,m;
matrix() {}
matrix(int _n,int _m): n(_n),m(_m) {memset(e,,sizeof(e));}
matrix operator * (const matrix &temp)const
{
matrix ret = matrix(n,temp.m);
for(int i=;i<=ret.n;i++)
{
for(int j=;j<=ret.m;j++)
{
for(int k=;k<=m;k++)
{
add(ret.e[i][j],1LL*e[i][k]*temp.e[k][j]%mod);
}
}
}
return ret;
}
matrix operator + (const matrix &temp)const
{
matrix ret = matrix(n,m);
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
add(ret.e[i][j],(e[i][j]+temp.e[i][j])%mod);
}
}
return ret;
}
void getE()
{
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
e[i][j] = i==j?:;
}
}
}
}; matrix qpow(matrix temp,int x)
{
int sz = temp.n;
matrix base = matrix(sz,sz);
base.getE();
while(x)
{
if(x & ) base = base * temp;
x >>= ;
temp = temp * temp;
}
return base;
} char way[] = {'A','T','C','G'};
struct Aho
{
struct state
{
int nxt[];
int fail,cnt;
}stateTable[MAX_Tot]; int find(char c) {for(int i=;i<;i++) if(c == way[i]) return i;} int size; queue<int> que; void init()
{
while(que.size()) que.pop();
for(int i=;i<MAX_Tot;i++)
{
memset(stateTable[i].nxt,,sizeof(stateTable[i].nxt));
stateTable[i].fail = stateTable[i].cnt = ;
}
size = ;
} void insert(char *s)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
int to = find(c);
if(!stateTable[now].nxt[to])
stateTable[now].nxt[to] = size++;
now = stateTable[now].nxt[to];
}
stateTable[now].cnt = ;
} void build()
{
stateTable[].fail = -;
que.push(); while(que.size())
{
int u = que.front();que.pop();
for(int i=;i<;i++)
{
if(stateTable[u].nxt[i])
{
if(u == ) stateTable[stateTable[u].nxt[i]].fail = ;
else
{
int v = stateTable[u].fail;
while(v != -)
{
if(stateTable[v].nxt[i])
{
stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
// 在匹配fail指针的时候顺便更新cnt
if(stateTable[stateTable[stateTable[u].nxt[i]].fail].cnt == )
stateTable[stateTable[u].nxt[i]].cnt = ;
break;
}
v = stateTable[v].fail;
}
if(v == -) stateTable[stateTable[u].nxt[i]].fail = ;
}
que.push(stateTable[u].nxt[i]);
}
/*****建立自动机nxt指针*****/
else
{
if(u == ) stateTable[u].nxt[i] = ;
else
{
int p = stateTable[u].fail;
while(p != - && stateTable[p].nxt[i] == ) p = stateTable[p].fail;
if(p == -) stateTable[u].nxt[i] = ;
else stateTable[u].nxt[i] = stateTable[p].nxt[i];
}
}
/*****建立自动机nxt指针*****/
}
}
} matrix build_matrix()
{
matrix ans = matrix(size,size);
for(int i=;i<size;i++)
{
for(int j=;j<;j++)
{
if(!stateTable[i].cnt && !stateTable[stateTable[i].nxt[j]].cnt)
ans.e[i+][stateTable[i].nxt[j]+]++;
}
}
return ans;
}
}aho; int main()
{
while(scanf("%d%d",&m,&n) == )
{
aho.init();
char s[];
for(int i=;i<=m;i++)
{
scanf("%s",s);
aho.insert(s);
}
aho.build();
matrix p = aho.build_matrix();
p = qpow(p,n);
int ans = ;
for(int i=;i<=aho.size;i++) add(ans, p.e[][i]);
printf("%d\n",ans);
}
return ;
}

POJ 2778 DNA Sequence —— (AC自动机+矩阵快速幂)的更多相关文章

  1. poj 2778 DNA Sequence ac自动机+矩阵快速幂

    链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...

  2. POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂

    这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...

  3. POJ 2778 DNA Sequence (AC自动机,矩阵乘法)

    题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...

  4. [poj2778]DNA Sequence(AC自动机+矩阵快速幂)

    题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列.(仅含A,T,C,G四个字符) 解题关键:AC自动机,实际上就是一个状态转移图,注意能少取模就少取模, ...

  5. 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 ...

  6. POJ 2778 DNA Sequence ( AC自动机、Trie图、矩阵快速幂、DP )

    题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析 : 这题搞了我真特么久啊,首先你需要知道的前置技能包括 AC自动机.构建Trie图.矩阵快速幂,其中矩 ...

  7. POJ 2778 DNA Sequence (AC自动机+DP+矩阵)

    题意:给定一些串,然后让你构造出一个长度为 m 的串,并且不包含以上串,问你有多少个. 析:很明显,如果 m 小的话 ,直接可以用DP来解决,但是 m 太大了,我们可以认为是在AC自动机图中,根据离散 ...

  8. poj2778DNA Sequence (AC自动机+矩阵快速幂)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud DNA Sequence Time Limit: 1000MS   Memory ...

  9. poj 2778 DNA Sequence AC自动机DP 矩阵优化

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

  10. poj 2778 DNA Sequence AC自动机

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

随机推荐

  1. Unable to resolve service for type 'Microsoft.AspNetCore.Http.IHttpContextAccessor'

    An unhandled exception occurred while processing the request. InvalidOperationException: Unable to r ...

  2. 改善C#程序的方法

    写在开头: http://www.cnblogs.com/luminji    157个建议_勘误表 一:属性 属性和方法一样.也可以是virtual和abstract. 条款2:运行时常量(read ...

  3. MVC的12种ActionResult介绍以及应用示例【转】

    一.介绍 1.ViewResult 表示一个视图结果,它根据视图模板产生应答内容.对应得Controller方法为View. 2.PartialViewResult 表示一个部分视图结果,与ViewR ...

  4. mysql8中查询语句表别名不能使用 “of”

    今天在迁移一个项目的时候,发现有一个sql报错,但是语句跟迁移之前完全一样,所以想来应该是 mysql 版本差异导致的. 迁移之前版本:5.6.28(腾讯云) 迁移之后版本:8.0.16(阿里云) 新 ...

  5. C++ 容器一图以蔽之

    读完C++ primary 容器相关章节,有必要总结一下容器的要点,一图说明. 其中的问题,以下是我的一些想法,欢迎交流. 问题1. STL源码剖析 · vector 问题2. STL源码剖析 · R ...

  6. char str = '1.2.';问题

    偶然看到群里老哥问道这个问题 #include <iostream> using namespace std; int main() { char str = '1.2.'; ; } 什么 ...

  7. 免安装方式的Python之VSCode环境配置

    概述 本文旨在介绍免安装方式,在VSCode中搭建Python(3.73)的配置环境.至于Python是什么.它能做些什么,诸如此类的介绍均不在此文中介绍,相信能看此文的人,多多少少都会有些了解. V ...

  8. 【vue开发】vue导出Excel表格教程&demo

    前端工作量最多的就是需求,需求就是一直在变,比如当前端数据写完之后,需要用Excel把数据下载出来:再比如前端在没有数据库想写些demo玩时,也是很好的选择. 第一步安装依赖包,修改配置 1.装依赖: ...

  9. python Beautiful Soup 采集it books pdf,免费下载

    http://www.allitebooks.org/ 是我见过最良心的网站,所有书籍免费下载 周末无聊,尝试采集此站所有Pdf书籍. 采用技术 python3.5 Beautiful soup 分享 ...

  10. python_datetime模块和time模块

    1.datetime模块 获取当前时间: import datetime # 获取当前时间 ctime = datetime.datetime.now() print(ctime) 只显示:年-月-日 ...