题目:传送门

题意: 给你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. 状态机的Verilog写法

    “硬件设计很讲究并行设计思想,虽然用Verilog描述的电路大都是并行实现的,但是对于实际的工程应用,往往需要让硬件来实现一些具有一定顺序的工作,这就要用到状态机思想.什么是状态机呢?简单的说,就是通 ...

  2. JavaScript Web API 全选反选案例

    全选反选 全选和反选功能,在开发中可以说是应用得非常多的,以下通过案例分解,学习如何使用JS实现全选反选功能. 该功能可分为如下三大步骤: 1.全选 1.1 获取父checkbox,注册点击事件 1. ...

  3. 方法1:使用Jenkins构建Docker镜像 --SpringCloud

    前提意义: SpringCloud微服务里包含多个文件夹,拉取仓库的所有代码,然后过根据选项参数使用maven编译打包指定目录的jar,然后再根据这个目录的Dockerfile文件制作Docker镜像 ...

  4. Spring Aop中execution的语法

    参考地址:https://blog.csdn.net/zz210891470/article/details/54175107 execution(* com.sample.service.impl. ...

  5. quartz 定时器执行

    类存储job信息 public class JobInfo {//省略setter getter String jobName; String jobGroup; Class<? extends ...

  6. screen命令下,自启动设置

    建立autostart.sh文件 #!/bin/bash screen_name=$"coffeetest:9100" screen -dmS $screen_name cmd=$ ...

  7. 5G能带来什么改变-从鸿蒙OS说起

    背景 从5G投票事件开始,开始关注5G.许多文章都说到5G的特点有速度快.时延低,其中,时延低是最重要的特点.然而,时延低能给社会带来什么改变呢? 2G是短信的时代,3G促成了语音视频,4G促成了短视 ...

  8. django路由系统及分发路由的本质

    路由系统 当我们启动一个django项目后,想要通过浏览器访问到django项目中的资源 就需要在django中的urls项目中进行路由配置 urlpatterns = [ url(r'^admin/ ...

  9. C++ Win32 遍历窗口

    查找指定窗口 #include <iostream> #include <windows.h> using namespace std; int main() { TCHAR ...

  10. scrapy RuntimeError: maximum recursion depth exceeded while calling a Python object 超出python最大递归数异常

    2019-10-21 19:01:00 [scrapy.core.engine] INFO: Spider opened2019-10-21 19:01:00 [scrapy.extensions.l ...