POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解
题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个
思路:因为要不包含模式串,显然又是ac自动机。因为n很大,所以用dp不太好。
在图论中,如果我们知道一个图的邻接矩阵A,$A_{ij}$ = 1表示i走一步到j有一条路,那么$A^n$中的$A_{ij}$就是这个图中从i走n步到j的路径数。
所以用ac自动机我们创造一个所有后缀的邻接矩阵A,那么用矩阵快速幂$A^n$就求出了所有的路径数,$\sum_{i = 1}^n A_{0i}$就是从root走到所有可行后缀的所有走法。
代码:
#include<cmath> #include<set> #include<map> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include <iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 100 + 5; const int M = 50 + 5; const ull seed = 131; const double INF = 1e20; const int MOD = 100000; int m, tn; ll n; struct Mat{ll s[maxn][maxn]; }; Mat mul(Mat &a, Mat &b){Mat t;memset(t.s, 0, sizeof(t.s));for(int i = 0; i < tn; i++){for(int j = 0; j < tn; j++){for(int k = 0; k < tn; k++){t.s[i][j] = (t.s[i][j] + a.s[i][k] * b.s[k][j])%MOD;}}}return t; } Mat ppow(Mat a, ll b){Mat ret;memset(ret.s, 0, sizeof(ret.s));for(int i = 0; i < maxn; i++) ret.s[i][i] = 1;while(b){if(b & 1) ret = mul(ret, a);a = mul(a, a);b >>= 1;}return ret; } int id(char a){if(a == 'A') return 0;if(a == 'T') return 1;if(a == 'C') return 2;if(a == 'G') return 3; } struct Aho{struct state{int next[4];int fail, cnt;}node[maxn];int size;queue<int> q;void init(){size = 0;newtrie();while(!q.empty()) q.pop();}int newtrie(){memset(node[size].next, 0, sizeof(node[size].next));node[size].cnt = node[size].fail = 0;return size++;}void insert(char *s){int len = strlen(s);int now = 0;for(int i = 0; i < len; i++){int c = id(s[i]);if(node[now].next[c] == 0){node[now].next[c] = newtrie();}now = node[now].next[c];}node[now].cnt = 1;}void build(){node[0].fail = -1;q.push(0);while(!q.empty()){int u = q.front();q.pop();if(node[node[u].fail].cnt && u) node[u].cnt = 1; //都不能取for(int i = 0; i < 4; i++){if(!node[u].next[i]){if(u == 0)node[u].next[i] = 0;elsenode[u].next[i] = node[node[u].fail].next[i];}else{if(u == 0) node[node[u].next[i]].fail = 0;else{int v = node[u].fail;while(v != -1){if(node[v].next[i]){node[node[u].next[i]].fail = node[v].next[i];break;}v = node[v].fail;}if(v == -1) node[node[u].next[i]].fail = 0;}q.push(node[u].next[i]);}}}}void query(){Mat a;memset(a.s, 0, sizeof(a.s));for(int i = 0; i < size; i++){for(int j = 0; j < 4; j++){if(node[node[i].next[j]].cnt == 0){a.s[i][node[i].next[j]]++;}}}a = ppow(a, n);ll ans = 0;for(int i = 0; i < size; i++){if(node[i].cnt == 0) ans = (ans + a.s[0][i]) % MOD;}printf("%lld\n", ans);}}ac; char s[20]; int main(){while(~scanf("%d%lld", &m, &n)){ac.init();while(m--){scanf("%s", s);ac.insert(s);}ac.build();tn = ac.size;ac.query();}return 0; }
转载于:https://www.cnblogs.com/KirinSB/p/11180526.html
POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解相关推荐
- POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]
http://poj.org/problem?id=2778 题意:给一些只由ACGT组成的模式串,问有多少种长度为n且不含有给出的模式串的DNA序列. 自动机的状态转换可以看成一个有向图(有重边的) ...
- POJ - 2778 DNA Sequence(AC自动机+矩阵快速幂)
题目链接:点击查看 题目大意:给出 n 个长度不大于 10 的字符串表示病毒串,再给出一个长度 len ,问长度为 len 的字符串中,有多少个字符串不含有病毒串作为子串 题目分析:因为病毒串的长度和 ...
- poj2778DNA Sequence (AC自动机+矩阵快速幂)
转载请注明出处: http://www.cnblogs.com/fraud/ --by fraud DNA Sequence Time Limit: 1000MS Memory ...
- L. Poor God Water(ACM-ICPC 2018 焦作赛区网络预赛,ac自动机+矩阵快速幂 或 BM线性递推)
描述 God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells hi ...
- poj 2778 AC自动机+矩阵快速幂
题目链接:https://vjudge.net/problem/POJ-2778 题意:输入n和m表示n个病毒,和一个长为m的字符串,里面只可以有'A','C','G','T' 这四个字符,现在问这个 ...
- HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- HDU - 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
题目链接:点击查看 题目大意:给出 n 个词根,现在要求出长度不大于 len 的单词中,有多少单词包含至少一个词根 题目分析:如果我们反过来想,也就是求出来总的单词数,然后减去不包含词根的单词数,剩下 ...
- POJ 2778 DNA Sequence —— (AC自动机+矩阵快速幂)
距离上次做AC自动机有很久了=.=,以前这题的思路死活看不懂,现在还是觉得很好理解的. 思路参见:http://blog.csdn.net/morgan_xww/article/details/783 ...
- POJ 2778 DNA Sequence (自动机DP+矩阵快速幂)
题意:给出m个致病DNA片段,求长为n且不含致病片段的DNA序列共有多少种. 数据范围:0 <= m <= 10,1 <= n <=2000000000 这题初看起来与上一题差 ...
- 【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)
已经128天了?怎么觉得上次倒计时150天的日子还很近啊 ....好吧为了把AC自动机搞透我也是蛮拼的..把1030和这道题对比了无数遍...最终结论是...无视时间复杂度,1030可以用这种写法解. ...
最新文章
- day09_读写分离_组件介绍
- 你面试稳了!通关LeetCode刷题完整攻略,省时又高效
- 通信专业学python有用吗-通信算法工程师需要学python吗
- word受权限保护无法打开_双击文档无法打开到底是啥毛病?简单一招解决
- npm ERR! code EINTEGRITY npm ERR! sha1- 报错解决办法
- 【知识连载】 如何用钉钉宜搭制定企业疫情防控数字化管理方案
- ES11新特性_动态import---JavaScript_ECMAScript_ES6-ES11新特性工作笔记065
- Symantec 不用密码卸载
- 从零开始学WEB前端——HTML理论讲解
- GitLab oauth2.0 第三方登录 单点登录
- swfobject java_[Java教程]swfobject.js视频播放插件
- 【经验分享】U盘软刷映泰TB250-BTC刷魔改BIOS上6789代CPU,另解决开机转一下后停止问题
- 6U VPX 高性能数据存储板 (2 片XC7K325T)
- webpack源码解析系列(一)
- Oracle TFA日志收集工具简介
- 问题 F: 解救小哈
- 一个简单的例子让你理解强化学习是什么,和有监督学习的区别又是什么
- 计算跑步时的能量消耗(卡路里和千焦的换算公式)
- java高级架构师工资多少啊,附源代码
- Python数据处理之一:数据读取
热门文章
- 【SDOI2014】数表
- 无外网环境下CentOS 7安装MySQL 5.7.18
- c#调用c++ dll的一个例子
- struts实现文件下载
- mysql安装手册(2)
- intellij 出现“Usage of API documented as @since 1.8+”的解决办法
- 阿里技术小哥,写了一个“​废话生成器”!火爆内网,演绎了什么叫“阿里味“!...
- 我们公司不会用分布式事务!
- 牛逼!这么问 OutOfMemoryError 能让我懵逼!
- 美团技术leader:写给工程师的十条精进原则