POJ 2778 DNA Sequence ( Trie图、矩阵快速幂 )
题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个
分析:
我们先分析Tire 图的结构 : Trie图是在AC自动机的原型上增添边使得状态可以快速转移,标记危险的节点(后缀是不良单词的节点); 那我们是想构造长度是n不包含不良串对不对 , 那是不是在trie图上从0节点走n步到安全节点的方案数(Trie图也是状态转移图)
在一个有向图中,A走k步到B的方案数(这显然是经典的矩阵快速幂问题),(原理需要自己搜索)先对原图建立一个邻接表M[i][j] , M[i][j] =1表示i到j有边直接相连,然后ans=pow(M,k) ,ans[A][B] 为答案
#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std; const int Max_Tot = 1e2 + ;
const int Letter = ;
const int MOD = 1e5;
int maxn;
int mp[]; struct mat{ int m[][]; }unit, M; mat operator * (mat a, mat b)
{
mat ret;
long long x;
for(int i=; i<maxn; i++){
for(int j=; j<maxn; j++){
x = ;
for(int k=; k<maxn; k++){
x += (long long)a.m[i][k]*b.m[k][j];
}
ret.m[i][j] = x % MOD;
}
}
return ret;
} inline void init_unit() { for(int i=; i<maxn; i++) unit.m[i][i] = ; } mat pow_mat(mat a, int n)
{
mat ret = unit;
while(n){
if(n&) ret = ret * a;
a = a*a;
n >>= ;
}
return ret;
} struct Aho{
struct StateTable{
int Next[Letter];
int fail, flag;
}Node[Max_Tot];
int Size;
queue<int> que; inline void init(){
while(!que.empty()) que.pop();
memset(Node[].Next, , sizeof(Node[].Next));
Node[].fail = Node[].flag = ;
Size = ;
} inline void insert(char *s){
int now = ;
for(int i=; s[i]; i++){
int idx = mp[s[i]];
if(!Node[now].Next[idx]){
memset(Node[Size].Next, , sizeof(Node[Size].Next));
Node[Size].fail = Node[Size].flag = ;
Node[now].Next[idx] = Size++;
}
now = Node[now].Next[idx];
}
Node[now].flag = ;
} //1) 如果son[i]不存在,将它指向 当前结点now的fail指针指
//向结点的i号后继(保证一定已经计算出来)。 //2) 如果son[i]存在,将它的fail指针指向 当前结点now的fail
//指针指向结点的i号后继(保证一定已经计算出来)。
inline void BuildFail(){
Node[].fail = ;
for(int i=; i<Letter; i++){
if(Node[].Next[i]){
Node[Node[].Next[i]].fail = ;
que.push(Node[].Next[i]);
}else Node[].Next[i] = ;///必定指向根节点
}
while(!que.empty()){
int top = que.front(); que.pop();
if(Node[Node[top].fail].flag) Node[top].flag = ;
for(int i=; i<Letter; i++){
int &v = Node[top].Next[i];
if(v){
que.push(v);
Node[v].fail = Node[Node[top].fail].Next[i];
}else v = Node[Node[top].fail].Next[i];
}
}
} inline void BuildMatrix(){
for(int i=; i<Size; i++)
for(int j=; j<Size; j++)
M.m[i][j] = ;
for(int i=; i<Size; i++){
for(int j=; j<Letter; j++){
if(!Node[i].flag && !Node[ Node[i].Next[j] ].flag)
M.m[i][Node[i].Next[j]]++;
}
}
maxn = Size;
} }ac; char S[];
int main(void)
{
mp['A']=,
mp['T']=,
mp['G']=,
mp['C']=;
int n, m;
while(~scanf("%d %d", &m, &n)){
ac.init();
for(int i=; i<m; i++){
scanf("%s", S);
ac.insert(S);
}
ac.BuildFail();
ac.BuildMatrix();
// for(int i=0; i<10; i++){
// for(int j=0; j<10; j++){
// printf("%d ", M.m[i][j]);
// }puts("");
// }puts(""); init_unit();
M = pow_mat(M, n); // for(int i=0; i<10; i++){
// for(int j=0; j<10; j++){
// printf("%d ", M.m[i][j]);
// }puts("");
// }puts(""); int ans = ;
for(int i=; i<ac.Size; i++)
ans += M.m[][i];
ans %= MOD;
printf("%d\n", ans);
}
return ;
}
POJ 2778 DNA Sequence ( Trie图、矩阵快速幂 )的更多相关文章
- poj 2778 DNA Sequence ac自动机+矩阵快速幂
链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...
- POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂
这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...
- [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自动机,矩阵乘法)
题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...
- poj 2778 AC自己主动机 + 矩阵高速幂
// poj 2778 AC自己主动机 + 矩阵高速幂 // // 题目链接: // // http://poj.org/problem?id=2778 // // 解题思路: // // 建立AC自 ...
- POJ 2778 DNA Sequence ( AC自动机、Trie图、矩阵快速幂、DP )
题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析 : 这题搞了我真特么久啊,首先你需要知道的前置技能包括 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 ...
- POJ 2778 DNA Sequence (矩阵快速幂 + AC自动鸡)
题目:传送门 题意: 给你m个病毒串,只由(A.G.T.C) 组成, 问你生成一个长度为 n 的 只由 A.C.T.G 构成的,不包含病毒串的序列的方案数. 解: 对 m 个病毒串,建 AC 自动机, ...
随机推荐
- 14.AutoMapper 之依赖注入(Dependency Injection)
https://www.jianshu.com/p/f66447282780 依赖注入(Dependency Injection) AutoMapper支持使用静态服务定位构建自定义值解析器和自定 ...
- 利用bing图片搜索接口开发图片搜索应用程序
概述:通过bing的图片搜索引擎,开发自己的图片搜索应用程序.bing的图片搜索接口是收费的,但是初次注册使用,key可以免费试用30天 程序运行效果如下 一,代码如下 static SearchRe ...
- javaScript运动框架之匀速运动
运动框架 1.在开始运动时,关闭已有定时器 2.把运动和停止隔开(if/else) 匀速运动的停止条件 运动终止条件:距离足够近 Demo代码 <!DOCTYPE html> <ht ...
- 搭建CocoaPods远程私有库
1.创建自己的远程私有索引库,用来存放私有框架的.podspec文件,并将其添加到本地索引 我用的仓库是码云(https://gitee.com),用自己的账号新建一个私有仓库,我命名为Private ...
- init_module - 初始化一条可加载模块的记录.
总览 #include <linux/module.h> int init_module(const char *name, struct module *image); 描述 init_ ...
- Electron 5.0 发布
Electron 5.0的主要变化 打包应用程序现在的行为与默认应用程序相同.将创建一个默认的应用程序菜单(除非应用程序有一个),并且将自动处理全部关闭窗口的事件. (除非应用程序处理事件) 现在默认 ...
- openCV for python的使用
一.openCV简介 OpenCV是一个开源的跨平台计算机视觉库.它轻量级而且高效——由一系列 C 函数和少量C++类构成,同时提供了Python.Ruby.MATLAB等语言的接口,实现了图像处理和 ...
- synology nas
synology nas synology nas synology nas https://www.synology.cn/zh-cn
- pyinstaller 打包工具的使用方法
pyinstaller的安装 下载后可以输入pip list查看是否安装成功 然后切换到项目的根目录输入 pyinstaller -i favicon.ico -w -c game.py -p Que ...
- windows CMD常用基础命令
一.ping 主要是测试本机TCP/IP协议配置正确性与当前网络现状. ping命令的基本使用格式是: ping IP地址/主机名/域名 [-t] [-a] [-n count] [-l size] ...