poj 2778 AC自动机+矩阵快速幂
题目链接:https://vjudge.net/problem/POJ-2778
题意:输入n和m表示n个病毒,和一个长为m的字符串,里面只可以有'A','C','G','T' 这四个字符,现在问这个长为m的字符串里面不可以出现任何病毒的情况有多少。
参考的两篇博客:
http://www.cnblogs.com/LQLlulu/p/9344774.html
https://blog.csdn.net/morgan_xww/article/details/7834801
上面的博客写得很好,可以主要看上面的博客(两个一起看)。
写点东西,不一定对。
因为最多10个病毒,每个病毒最多10个字符,所以我们trie树上最多有100个点,其他空的点都指向根节点(也就是说我们把所有的空的节点看成0),这样我们可以到达的点就只有100个(再重复一遍:我们把trie树上面的空节点一律指向根节点,看成0),同时因为有些点是单词的结尾或者他的fail[u]是单词结尾(fail[u]是单词结尾说明当前位置的后缀和fail[u]上的单词相同,这个后缀也不能到达)。
我们一开始先构建一个cnt*cnt的邻接矩阵mat(cnt是trie树上面的节点个数),刚刚构建的mat[i][j]代表从编号为i的点走一步到达编号为j的点的合法(就是不经过单词结尾或fail[u]是单词结尾的点),在离散数学里面有一个结论,就是已知cnt个点之间两两互达(走一步)的可能数量(就是这个cnt*cnt的矩阵已经有了),那么如果我们要计算他们两两之间走n步到达的可能数量,只需要求出矩阵的n次方,这个矩阵的n次方就是点与点之间走n步到达的可能数量,这个可以联想矩阵乘法的计算过程。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<set>
#include<cstdio>
#include<string>
#include<deque>
using namespace std;
typedef long long LL;
#define eps 1e-8
#define INF 0x3f3f3f3f
#define maxn 105
],fail[maxn],val[maxn];
LL mat[maxn][maxn],f[maxn][maxn],ss[maxn][maxn];
//mat[i][j]记录从i到j有多少种可能,f[0][i]记录以i结束的合法可能,其它维没用,ss用来计算时暂时存储
int n,m,k,t,cnt;
];
void init(){
memset(trie,,sizeof(trie));
memset(fail,,sizeof(fail));
memset(val,,sizeof(val));
memset(mat,,sizeof(mat));
memset(f,,sizeof(f));
f[][]=; //一开始把根节点赋值为1,因为我们只需要第一行,所以可以只把f[0][0]赋值为1
/*for(int i=0;i<maxn;i++)
f[i][i]=1; */ //也可以这样
cnt=;
}
int getID(char a){
if(a=='A')
;
if(a=='T')
;
if(a=='C')
;
if(a=='G')
;
}
void insert(char *s){
;
;s[i];i++){
int id=getID(s[i]);
)
trie[root][id]=++cnt;
root=trie[root][id];
}
val[root]=;//标记单词结尾
}
void build_fail(){
queue<int>q;
;
;i<;i++){
if(trie[root][i])
q.push(trie[root][i]);
}
while(!q.empty()){
int u=q.front();
q.pop();
if(val[fail[u]])//如果这个后缀是一个病毒,那么这个后缀也不可以到达
val[u]=;
;i<;i++){
if(trie[u][i]){
fail[trie[u][i]]=trie[fail[u]][i];
q.push(trie[u][i]);
}else{
trie[u][i]=trie[fail[u]][i];
}
}
}
}
void build_mat(){//建图
;i<=cnt;i++){
;j<;j++){
&&val[i]==)//当前状态或接下来的的状态是病毒都是不可以到达的
mat[i][trie[i][j]]++;
}
}
}
void muti(LL a[][maxn],LL b[][maxn]){//矩阵快速幂
memset(ss,,sizeof(ss));
;k<=cnt;k++)
;i<=cnt;i++){
;j<=cnt;j++){
ss[i][j]+=a[i][k]*b[k][j];
ss[i][j]%=;
}
}
;i<=cnt;i++){
;j<=cnt;j++){
a[i][j]=ss[i][j];
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF){
init();
;i<n;i++){
scanf("%s",s);
insert(s);
}
build_fail();
build_mat();//获得走1步时的矩阵
while(m){
)
muti(f,mat);
muti(mat,mat);
m>>=;
}
LL ans=;
;i<=cnt;i++)
ans=(ans+f[][i])%;
printf("%lld\n",ans);
}
;
}
poj 2778 AC自动机+矩阵快速幂的更多相关文章
- 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 ~ HDU - 2243 AC自动机+矩阵快速幂
这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...
- POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解
题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...
- 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 ...
- POJ 2778 DNA Sequence (矩阵快速幂 + AC自动鸡)
题目:传送门 题意: 给你m个病毒串,只由(A.G.T.C) 组成, 问你生成一个长度为 n 的 只由 A.C.T.G 构成的,不包含病毒串的序列的方案数. 解: 对 m 个病毒串,建 AC 自动机, ...
- POJ 2778 (AC自动机+矩阵乘法)
POJ 2778 DNA Sequence Problem : 给m个只含有(A,G,C,T)的模式串(m <= 10, len <=10), 询问所有长度为n的只含有(A,G,C,T)的 ...
- 考研路茫茫——单词情结 HDU - 2243 AC自动机 && 矩阵快速幂
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- POJ2778 DNA Sequence(AC自动机+矩阵快速幂)
题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个 ...
- hdu 2243 考研路茫茫——单词情结 ac自动机+矩阵快速幂
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2243 题意:给定N(1<= N < 6)个长度不超过5的词根,问长度不超过L(L <23 ...
随机推荐
- Java中的io流学习(了解四大基类和基本步骤)
Java中io流四大基类及io流操作四大基本步骤 io流:(input/output)即输入输出流.面向对象的思想之一是面向接口编程,面向父类编程,也就是多态.所以学好基类(父类)很重要. 分类 按处 ...
- Python解释器的安装
Python解释器的安装 作者:Eric 微信:loveoracle11g 下载Python Python-3.7.0(64-bit)下载链接地址: https://www.python.org/ft ...
- Egret飞行模拟-开发记录02
1.Egret异步加载资源制作loading界面 使用EUI,EXML组件制作loading界面时,需要皮肤主题资源加载控制.即default.thm.json配置文件. 下一篇专门记录这部分. 2. ...
- 关于shiro安全框架实现同一用户同一时刻仅可在一个地址登录的技术实现
首先,我们要说明一下,本技术点的开发背景是shiro与springMvc结合环境下的开发方式. 由于shiro把用户登录后的信息都存在了自己封装的session中,所以要实现单一地址登录,我们需要关注 ...
- windows下nginx的安装及使用(转载)
转载自:https://www.cnblogs.com/jiangwangxiang/p/8481661.html 1.下载nginx http://nginx.org/en/download.htm ...
- 强一致性hash实现java版本及强一致性hash原理
一致性 hash 分布式过程中我们将服务分散到若干的节点上,以此通过集体的力量提升服务的目的.然而,对于一个客户端来说,该由哪个节点服务呢?或者说对某个节点来说他分配到哪些任务呢? 强哈希 考虑到单服 ...
- start to use await
import { browser, $, $$, by, element, protractor } from "protractor"; //import { SearchPag ...
- iframe高度宽度自适应
iframe { width: 100%; height: 100%; border: none; position: inherit; } 网上全是js方法,而且略显臃肿,故找到了一个css方法,宽 ...
- 菜鸟教程之学习Shell script笔记(上)
菜鸟教程之学习Shell script笔记 以下内容是,学习菜鸟shell教程整理的笔记 菜鸟教程之shell教程:http://www.runoob.com/linux/linux-shell.ht ...
- python———day03
一.字符串格式化输出: 占位符 %s(字符串) %d(整数) %f(浮点数,约等于小数) name = input("Name:") age = input("Ag ...