题目:传送门

题意: 给你m个病毒串,只由(A、G、T、C) 组成, 问你生成一个长度为 n 的 只由 A、C、T、G 构成的,不包含病毒串的序列的方案数。

解: 对 m 个病毒串,建 AC 自动机, 然后, 这个AC自动机就类似于一张有向图, 可以用邻接矩阵存这张有向图。

  最多10个病毒串, 每个病毒串长度不超过 10, 那最多是个 100 * 100 的矩阵, 可以接受。

   最后用矩阵快速幂加速推导。

  

#include<cstdio>
#include<cstring>
#include<queue>
#define LL long long
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define mem(i, j) memset(i, j, sizeof(i))
#define pb push_back
using namespace std; const int N = , mod = ;
struct mat {
LL a[N][N];
mat() { mem(a, ); }
};
struct Trie {
int ch[N][], tot, metch[N], Fail[N];
void init() {
mem(ch[], ); tot = ; metch[] = ;
}
int get(char Q) {
if(Q == 'A') return ;
else if(Q == 'C') return ;
else if(Q == 'T') return ;
return ;
}
void join(char s[]) {
int now = ; int len = strlen(s);
rep(i, , len - ) {
int id = get(s[i]);
if(!ch[now][id]) {
mem(ch[tot], ); metch[tot] = ;
ch[now][id] = tot++;
}
now = ch[now][id];
}
metch[now] = ;
}
void getFail() {
queue<int> Q; while(!Q.empty()) Q.pop();
rep(i, , ) {
if(ch[][i]) {
Q.push(ch[][i]); Fail[ch[][i]] = ;
}
}
while(!Q.empty()) {
int now = Q.front(); Q.pop();
rep(i, , ) {
int u = ch[now][i];
if(u == ) ch[now][i] = ch[Fail[now]][i];
else {
Q.push(u);
Fail[u] = ch[Fail[now]][i];
metch[u] |= metch[Fail[u]];
}
}
}
}
mat getMat() {
mat A;
rep(i, , tot - ) {
if(metch[i]) continue;
rep(j, , ) {
if(!metch[ch[i][j]]) A.a[i][ch[i][j]]++;
}
}
return A;
}
};
Trie AC;
char b[];
mat mul(mat A, mat B, int n) {
mat C;
rep(i, , n) {
rep(j, , n) {
rep(k, , n) {
C.a[i][j] = (C.a[i][j] + A.a[i][k] * B.a[k][j]) % mod;
}
}
}
return C;
}
mat ksm(mat A, int B, int n) {
mat res; rep(i, , n) res.a[i][i] = ;
while(B) {
if(B & ) res = mul(res, A, n);
A = mul(A, A, n); B >>= ;
}
return res;
}
int main() {
int n, m;
while(~scanf("%d %d", &m, &n)) {
AC.init();
rep(i, , m) {
scanf("%s", b); AC.join(b);
}
AC.getFail();
mat A; A = AC.getMat();
mat ans = ksm(A, n, AC.tot - );
LL res = 0LL;
rep(i, , AC.tot - ) {
res = (res + ans.a[][i]) % mod;
}
printf("%lld\n", res);
}
return ;
}

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

  1. poj 3070 && nyoj 148 矩阵快速幂

    poj 3070 && nyoj 148 矩阵快速幂 题目链接 poj: http://poj.org/problem?id=3070 nyoj: http://acm.nyist.n ...

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

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

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

  4. POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解

    题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...

  5. POJ 2778 DNA Sequence ( Trie图、矩阵快速幂 )

    题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析: 我们先分析Tire 图的结构 : Trie图是在AC自动机的原型上增添边使得状态可以快速转移,标记危 ...

  6. POJ 2778 DNA Sequence(AC自动机+矩阵加速)

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9899   Accepted: 3717 Desc ...

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

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

  8. hdu-5667 Sequence(矩阵快速幂+费马小定理+快速幂)

    题目链接: Sequence Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) ...

  9. HDU - 1005 Number Sequence 矩阵快速幂

    HDU - 1005 Number Sequence Problem Description A number sequence is defined as follows:f(1) = 1, f(2 ...

随机推荐

  1. Linux组管理、用户管理、查看用户信息、usermod、which、切换用户、修改文件具体权限

    组管理 提示:创建组/删除组的终端命令都需要通过sudo执行 序号 命令 作用 01 groupadd组名 添加组 02 groupdel组名 删除组 03 cat/etc/group 确认组信息 0 ...

  2. 【LEETCODE】38、167题,Two Sum II - Input array is sorted

    package y2019.Algorithm.array; /** * @ProjectName: cutter-point * @Package: y2019.Algorithm.array * ...

  3. Python爬虫快速上手教程

    1 这个是什么        整理Python中requests常用的API 2 代码 from bs4 import BeautifulSoup import requests import re ...

  4. jvm调优相关

    查找占用cpu过高的线程,并排查原因 1.查找jvm进程 (1)jps -l (2)ps -ef|grep java 这一步骤可以得到进程号,假如进程号为9527 2.查找该jvm进程中占用cpu比较 ...

  5. 【转载】Javascript使用Math.random()随机数函数生成1至1000的随机数

    在Javascript代码编写过程中,有时候我们需要使用Js来生成随机数,清除ajax的get请求缓存的时候我们会带上一个随机数来解决此问题,此外在其他应用中也可能使用到随机数,在Javascript ...

  6. 安恒pwn魔法

    魔法这是比较基础的一道栈溢出: 首先看下开启的防护机制 Checksec magicc发现只有nx防护 我们载入ida发现溢出点 Buf实际溢出空间为0x16,构造exp import time fr ...

  7. python网络爬虫入门(二)

    刚去看了一下,18年2月份写了第一篇关于爬虫的文章(仅仅介绍了使用requests库去获取HTML代码),一年多之后看来很稚嫩也没有多少参考的意义,但没想着要去修改它,留着也是一个回忆吧.至少证明着我 ...

  8. Laravel5.6---搜索查询 自带paginate()分页 get传参

    laravel的paginate()分页,如果用post传参,点击第二页时会默认使用get,就会返回原始数据了 需要把查询数据get方式也放到paginate()分页参数中 一.路由 Route::g ...

  9. Linux命令——tree

    参考:Linux tree Command Tutorial for Beginners (6 Examples) 简介 Linux tree命令用于以树状图列出目录的内容. 执行tree指令,它会列 ...

  10. java加密算法-DES

    public class DESUtil { private static String strdefaultkey = "13456789abcd";//默认的key priva ...