DNA Sequence

给出m(m<=10)个长度不超过10的'A''T''G''C'序列,求长度为n(n<=2*1e9)的'A''T''G''C'序列不含上述m个序列中的任意一个序列的种类数。

首先出现了多个模板串,考虑Aho-Corasick,n的范围提示出要使用log级别的算法,并且能在Trie树上使用,矩阵是很好的选择,矩阵在有向图中的意义,可以求出s-t的方法数,因为矩阵的计算过程刚好满足乘法原理和加法原理,i行j列表示,i-j的方法数,例如以下矩阵

                                    |0,1,1,0|

                                      |0,0,0,1|这个矩阵就表示以下图形,

                                        |0,1,0,1|如果问从i,走到j走N步的方式,

                                      |0,0,0,0|那么就只需要矩阵n次幂,并输出i行j列的数字

然而Aho-Corasick实在Trie上实现的,而Trie是一个有向的图(树),那么就构建矩阵,并输出root节点编号的矩阵那一行的总和。在得到fail指针的时候要把整个图建好。

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <queue>
#include <cstring>
#include <algorithm>
#define LL long long//***
using namespace std;
const int N = 110;
const int mod = 100000;
int n,m,ncnt;
char ill[15];struct node{int id;bool flag;node *ch[4],*fail;void init(){flag = false;for(int i = 0;i < 4;++i)ch[i] = NULL;}
}trie[N*N];
int hash[128];//***
struct Matrix{LL map[N][N];void clear(){memset(map,0,sizeof(map));}
}c;node *newnode(){node *p = &trie[ncnt];p->init(); p->id = ncnt++;return p;
}void insert(node *root,char *s){node *p = root;while(*s != '\0'){if(p->ch[hash[*s]])p = p->ch[hash[*s]];else {p->ch[hash[*s]] = newnode();p = p->ch[hash[*s]];}++s;}p->flag = true;
}void Build(node *root){queue <node *> q;q.push(root);while(!q.empty()){node *p = q.front();q.pop();for(int i=0;i<4;++i){if(p->ch[i]){node *next = p->fail;while(next && !next->ch[i])next = next->fail;p->ch[i]->fail = next ? next->ch[i]:root;if(p->ch[i]->fail->flag)p->ch[i]->flag=true;//***q.push(p->ch[i]);}else p->ch[i] = (p == root) ? root:p->fail->ch[i];if(!p->ch[i]->flag)++c.map[p->id][p->ch[i]->id];}  }
}Matrix Matrix_mul(Matrix x,Matrix y){Matrix res;res.clear();for(int i = 0;i < ncnt;++i){for(int j = 0;j < ncnt;++j){for(int k = 0;k < ncnt;++k){res.map[i][j] = (res.map[i][j]+y.map[i][k]*x.map[k][j])%mod;}}}return res;
}Matrix Pow(Matrix x,int n){Matrix res;res.clear();for(int i = 0;i < ncnt;++i)res.map[i][i] = 1;while(n){if(n&1)res = Matrix_mul(res,x);x = Matrix_mul(x,x);n >>=1;}return res;
}void _fre(node *p){for(int i = 0;i < 4;++i){if(p->ch[i])_fre(p->ch[i]);}free(p);
}int main(){hash['A'] = 0,hash['C'] = 1,hash['G'] = 2,hash['T'] = 3;while(scanf("%d%d",&m,&n) != EOF){ncnt = 0;c.clear();memset(trie,0,sizeof(trie));node *root = newnode();for(int i = 0;i < m;++i){scanf("%s",ill);insert(root,ill);}Build(root);Matrix res = Pow(c,n);LL ans = 0;for(int i = 0;i < ncnt;++i){ans += res.map[0][i];ans %= mod;}cout<<ans<<endl;// _fre(root);莫名RE }return 0;
}

  

转载于:https://www.cnblogs.com/xgtao984/p/5701601.html

POJ 2778 DNA Sequence (Aho-Corasick 矩阵优化) - xgtao -相关推荐

  1. POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]

    http://poj.org/problem?id=2778 题意:给一些只由ACGT组成的模式串,问有多少种长度为n且不含有给出的模式串的DNA序列. 自动机的状态转换可以看成一个有向图(有重边的) ...

  2. POJ - 2778 DNA Sequence(AC自动机+矩阵快速幂)

    题目链接:点击查看 题目大意:给出 n 个长度不大于 10 的字符串表示病毒串,再给出一个长度 len ,问长度为 len 的字符串中,有多少个字符串不含有病毒串作为子串 题目分析:因为病毒串的长度和 ...

  3. POJ 2778 DNA Sequence —— (AC自动机+矩阵快速幂)

    距离上次做AC自动机有很久了=.=,以前这题的思路死活看不懂,现在还是觉得很好理解的. 思路参见:http://blog.csdn.net/morgan_xww/article/details/783 ...

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

    题意:给出m个致病DNA片段,求长为n且不含致病片段的DNA序列共有多少种. 数据范围:0 <= m <= 10,1 <= n <=2000000000 这题初看起来与上一题差 ...

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

    题目链接 MMM个病毒串,求长度为NNN的不包含病毒的字符串种类数 思路 把所有的病毒串建ACACAC自动机,failfailfail指针指向的节点如果标记过(包含病毒串)当前也是不合法串 . 然后我 ...

  6. data矩阵poj 2778 DNA Sequence

    最近研究data矩阵,稍微总结一下,以后继续补充: ac自动机处理字符串,dp计算谜底,用矩阵来减速 每日一道理 巴尔扎克说过"不幸,是天才的进升阶梯,信徒的洗礼之水,弱者的无底深渊&quo ...

  7. poj 2778 DNA Sequence

    http://poj.org/problem?id=2778 AC自动机 + 矩阵连乘 代码: #include<iostream> #include<cmath> #incl ...

  8. POJ 2778 AC自己主动机+矩阵幂 不错的题

    http://poj.org/problem?id=2778 有空再又一次做下,对状态图的理解非常重要 题解: http://blog.csdn.net/morgan_xww/article/deta ...

  9. 【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)

    已经128天了?怎么觉得上次倒计时150天的日子还很近啊 ....好吧为了把AC自动机搞透我也是蛮拼的..把1030和这道题对比了无数遍...最终结论是...无视时间复杂度,1030可以用这种写法解. ...

  10. poj2778 DNA Sequence (ACAM+dp+矩阵倍增)

    求不包含模式串的文本串个数,n极大.我们还是类似的建出ACAM,然后在上面跑dp,只不过这次我们要矩阵倍增来加速.复杂度O((m∗len)3logn)O((m*len)^3logn) #include ...

最新文章

  1. /etc/rc.d 与 /etc/profile或者./.bash_profile的区别
  2. fastdfs redis java,大文件上传_断点续传_文件分片传输_fastdfs_前后端一站式解决方案...
  3. aix oracle监听配置_LINUX系统下Oracle修改默认监听端口号操作
  4. i18n php_PHP国际化多语言的实现(非I18N)
  5. 3层vni vxlan_方便业务迁移,大型企业数据中心VXLAN大二层基础,一分钟了解下
  6. java 配置tomcat_为tomcat配置java环境变量
  7. Oracle11新特性——初始化文件管理
  8. 华为牛人在华为工作十年的感悟!--总结[华为的10年工作]
  9. 深度学习2.0-41.GRU原理及实战
  10. Junipor交换机 HAS BOOTED FROM THE BACKUP JUNOS IMAGE
  11. Windows下QT5.9构建的debug或release文件打包后不能使用
  12. (无人驾驶仿真软件整理)
  13. php开发之文件指针,文件锁定
  14. Vb中 继承 多态的实现
  15. (转)DEDECMS模板原理、模板标签学习 - .Little Hann
  16. 帆软:根据参数查看不同报表
  17. 安全狗再次入选中国数字安全百强报告
  18. SEO每天都是动态变化的,你要关注什么?
  19. 键盘的 SysRq按键使用详解
  20. 软件项目管理案例:假设50万的资金准备开设一间咖啡馆,请按照WBS原理将开设咖啡馆过程中所可能涉及的工作进行分解。

热门文章

  1. 大幅提高Android开发效率之TemplateBuilder
  2. nvm npm node
  3. 《TCP/IP详解卷1:协议》第12章 广播和多播---读书笔记
  4. 如何动态读取嵌入式资源
  5. 【VMware混合云】掀起你的盖头来
  6. java位图去重_Redis系列(3) Bloom/BitMap/Geo
  7. 大并发服务器不得不说的技术--TCP_CORK
  8. java exec 关闭,Java学习之使用Runtime.exec()启动、关闭Tomcat
  9. html轮播图显示失败_html简单的二级菜单制作
  10. python处理pdf文件_python处理操作pdf全攻略