POJ 2778 DNA Sequence (自动机DP+矩阵快速幂)
题意:给出m个致病DNA片段,求长为n且不含致病片段的DNA序列共有多少种。
数据范围:0 <= m <= 10,1 <= n <=2000000000
这题初看起来与上一题差不多,但一看数据范围就傻了……
分析:先建m个致病DNA片段的自动机,然后求出自动机中结点之间转移的路径数目,这样就可以得到一个有向图,所求问题就变为从根结点出发,到达任意一点,所走路径长度为n且路径不经过危险结点的路径数目。再抽象一下,就是求一个边长均为1的有向图中2点之间长为n的路径数目,这就不难想到矩阵了。设G为邻接矩阵,则Gk中第i行j列的元素表示从i到j长为k的路径数目。
#include <stdio.h> #include <string.h> #include <queue> using namespace std; #define M 11 #define LEN 15 #define SIZE (M*LEN) #define mod 100000typedef __int64 LL;int next[M*LEN][4]; int fail[M*LEN]; bool isend[M*LEN]; int m,n,node; LL mat[M*LEN][M*LEN]; LL tmp[M*LEN][M*LEN]; LL ans[M*LEN][M*LEN]; void init() {node=1;memset(next[0],0,sizeof(next[0])); } void add(int cur,int k) {memset(next[node],0,sizeof(next[node]));isend[node]=0;next[cur][k]=node++; } int hash(char c) {switch(c){case 'A': return 0;case 'C': return 1;case 'T': return 2;case 'G': return 3;} } void insert(char *s) {int i,k,cur;for(i=cur=0;s[i];i++){k=hash(s[i]);if(!next[cur][k]) add(cur,k);cur=next[cur][k];}isend[cur]=1; } void build_ac() {queue<int>q;int cur,nxt,tmp;fail[0]=0;q.push(0);while(!q.empty()){cur=q.front(),q.pop();for(int k=0;k<4;k++){nxt=next[cur][k];if(nxt){if(cur==0) fail[nxt]=0;else{for(tmp=fail[cur];tmp && !next[tmp][k];tmp=next[tmp][k]);fail[nxt]=next[tmp][k];}if(isend[fail[nxt]]) isend[nxt]=1;q.push(nxt);}else{next[cur][k]=next[fail[cur]][k];}}} } void build_mat() {int cur,nxt,k;memset(mat,0,sizeof(mat));for(cur=0;cur<node;cur++){if(isend[cur]) continue;for(k=0;k<4;k++){nxt=next[cur][k];if(!isend[nxt]) mat[cur][nxt]++;}} } void mat_mul(LL a[][SIZE],LL b[][SIZE]) {for(int i=0;i<node;i++){for(int j=0;j<node;j++){tmp[i][j]=0;for(int k=0;k<node;k++){tmp[i][j]+=a[i][k]*b[k][j];}tmp[i][j]%=mod;}} } void mat_pow(int k) {memset(ans,0,sizeof(ans));for(int i=0;i<node;i++) ans[i][i]=1;while(k){if(k&1){mat_mul(ans,mat);memcpy(ans,tmp,sizeof(tmp));}k>>=1;mat_mul(mat,mat);memcpy(mat,tmp,sizeof(tmp));} } void solve() {build_ac();build_mat();mat_pow(n);LL ret=0;for(int i=0;i<node;i++) ret+=ans[0][i];printf("%I64d\n",ret%mod); } int main() {char s[LEN];while(~scanf("%d%d",&m,&n)){init();for(int i=0;i<m;i++){scanf("%s",s);insert(s);}solve();}return 0; }
转载于:https://www.cnblogs.com/algorithms/archive/2012/08/08/2628813.html
POJ 2778 DNA Sequence (自动机DP+矩阵快速幂)相关推荐
- 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂
[题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...
- [BJOI2017]魔法咒语(AC自动机+DP+矩阵快速幂)
文章目录 title solution code title solution 针对数据编程才是坠吊的!!! 观察数据,发现分隔数据的 L L L跨度过大,没有衔接--推测很有可能是分数据做法 ①:考 ...
- 第九届河南省赛 宣传墙 //状压dp+矩阵快速幂+dfs
http://nyoj.top/problem/1273 状压dp+矩阵快速幂+dfs 1273-宣传墙 内存限制:64MB 时间限制:1000ms 特判: No 通过数:19 提交数:64 难度:4 ...
- Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】
题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...
- 【BZOJ】2553: [BeiJing2011]禁忌 AC自动机+期望+矩阵快速幂
[题意]给定n个禁忌字符串和字符集大小alphabet,保证所有字符在集合内.一个字符串的禁忌伤害定义为分割能匹配到最多的禁忌字符串数量(一个可以匹配多次),求由字符集构成的长度为Len的字符串的期望 ...
- POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]
http://poj.org/problem?id=2778 题意:给一些只由ACGT组成的模式串,问有多少种长度为n且不含有给出的模式串的DNA序列. 自动机的状态转换可以看成一个有向图(有重边的) ...
- POJ - 2778 DNA Sequence(AC自动机+矩阵快速幂)
题目链接:点击查看 题目大意:给出 n 个长度不大于 10 的字符串表示病毒串,再给出一个长度 len ,问长度为 len 的字符串中,有多少个字符串不含有病毒串作为子串 题目分析:因为病毒串的长度和 ...
- POJ - 3613 Cow Relays(Floyd思想+矩阵快速幂+动态规划)
题目链接:点击查看 题目大意:给定一张由T(T<=100)条边构成的无向图,点的编号为1~1000,之间的整数,求从起点S到终点E恰好经过N(N<=1e6)条边(可重复经过)的最短路 题目 ...
- BZOJ 2004 公交线路(状压DP+矩阵快速幂)
注意到每个路线相邻车站的距离不超过K,也就是说我们可以对连续K个车站的状态进行状压. 然后状压DP一下,用矩阵快速幂加速运算即可. #include <stdio.h> #include ...
最新文章
- R语言获取当前R版本(version)实战
- iOS学习9_事件分发amp;响应链
- 俄罗斯机器人雄鹿_在雄鹿无球可打,在火箭重获新生!哈登,你又让一人打出身价...
- python中hashmap的方法_如何为Java的HashMap模拟Python的dict的“ items(...
- K8S精华问答 | CentOS下如何配置主机互信?
- Linux生成随机数字和字符串
- 【HDU5482】Numquam vincar,暴力(da biao)预处理+组合数
- 华为数据之道_数字化与数据治理的典范实践者 | 华为数据之道
- Spanning Tree Protocol介绍
- mock模拟的数据能增删改查吗_新课通知: React+Umi3+Typescript+Mock
- bboss_spring_struts2_myibatis对比分析
- 给Jquery easyui 的datagrid 每行添加操作链接
- outlook 表格使用技巧
- 接口没获取到就被使用_使用CompletableFuture时,那些令人头疼的问题
- nbu备份本机oracle,大话nbu九(nbu异机备份恢复oracle)
- java-清楚明了的集合
- 2023适老用品展、CISSE北京养老展、老年产业博览会
- php数字转换百千万,PHP数字金额转换成中文大写显示
- c++ 鼠标切换形状
- 硬件设计——MOS管实际应用详解