poj_2778_DNA Sequence(AC自动机+矩阵)
题意:
有m个模式串,然后给你一个长度n,问你n长度的DNA序列有多少种不包含这m个模式串
题解:
这题显然要用AC自动机,将模式串的AC自动机建好后,再构建矩阵,矩阵的含义是自动机中0~tot的节点走一步到0~tot的节点的方案数,然后要走n步,所以上一个矩阵快速幂就行了,在建AC自动机的时候要改变一下失败指针的指向,不存在的节点就指向当前节点的失败指针,这样就模拟了AC自动机的匹配过程,需要画图好好理解一下。
- #include<cstdio>
- #include<cstring>
- #define mst(a,b) memset(a,b,sizeof(a))
- #define F(i,a,b) for(int i=a;i<=b;i++)
- typedef long long ll;
- //-----------------------矩阵-------------------------
- const int mat_N=*+,mo=1e5;//矩阵阶数,取膜
- int N;
- struct mat{
- ll c[mat_N][mat_N];
- void init(){mst(c,);}
- mat operator*(mat b){
- mat M;M.init();
- F(i,,N)F(j,,N)F(k,,N)M.c[i][j]=(M.c[i][j]+c[i][k]*b.c[k][j])%mo;
- return M;
- }
- mat operator+(mat b){
- mat M;
- F(i,,N)F(j,,N)M.c[i][j]=(c[i][j]+b.c[i][j])%mo;
- return M;
- }
- mat operator^(ll k){
- mat ans,M=(*this);ans.init();
- F(i,,N)ans.c[i][i]=;
- while(k){if(k&)ans=ans*M;k>>=,M=M*M;}
- return ans;
- }
- }A;
- //-----------------------AC自动机-----------------------
- const int AC_N=*,tyn=;//数量乘串长,类型数
- struct AC_automation{
- int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
- inline int getid(char x){
- if(x=='A')return ;
- if(x=='T')return ;
- if(x=='G')return ;
- if(x=='C')return ;
- }
- void nw(){cnt[++tot]=;memset(tr[tot],-,sizeof(tr[tot]));}
- void init(){tot=-,fail[]=-,nw();}
- void insert(char *s,int x=){
- for(int len=strlen(s),i=,w;i<len;x=tr[x][w],i++)
- if(tr[x][w=getid(s[i])]==-)nw(),tr[x][w]=tot;
- cnt[x]++;//串尾标记
- }
- void build(int head=,int tail=){
- for(Q[++tail]=;head<=tail;){
- for(int i=,x=Q[head++],p=-;i<tyn;i++)if(~tr[x][i]){
- if(x==)fail[tr[][i]]=;
- else for(p=fail[x],fail[tr[x][i]]=;~p;p=fail[p])
- if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;}
- if(cnt[fail[tr[x][i]]])cnt[tr[x][i]]=;
- Q[++tail]=tr[x][i];
- }else if(x==)tr[x][i]=;
- else tr[x][i]=tr[fail[x]][i];
- }
- }
- }AC;
- void build_mat()
- {
- A.init();
- F(i,,AC.tot)F(j,,)if(!AC.cnt[i]&&!AC.cnt[AC.tr[i][j]])A.c[i][AC.tr[i][j]]++;
- }
- int main()
- {
- ll n,m,ans;char buf[];
- while(~scanf("%lld%lld",&n,&m))
- {
- AC.init();
- F(i,,n)scanf("%s",buf),AC.insert(buf);
- AC.build(),N=AC.tot,build_mat(),A=A^m,ans=;
- F(i,,AC.tot)ans+=A.c[][i];
- printf("%lld\n",ans%mo);
- }
- return ;
- }
poj_2778_DNA Sequence(AC自动机+矩阵)的更多相关文章
- poj2778DNA Sequence (AC自动机+矩阵快速幂)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud DNA Sequence Time Limit: 1000MS Memory ...
- POJ2778 DNA Sequence(AC自动机 矩阵)
先使用AC自动机求得状态转移关系,再建立矩阵,mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数,则此矩阵的n次方表示n步从i,到j的方法数. #include<cstdio& ...
- poj 2778 DNA Sequence ac自动机+矩阵快速幂
链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...
- POJ 2778 DNA Sequence (AC自动机,矩阵乘法)
题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...
- 【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)
已经128天了?怎么觉得上次倒计时150天的日子还很近啊 ....好吧为了把AC自动机搞透我也是蛮拼的..把1030和这道题对比了无数遍...最终结论是...无视时间复杂度,1030可以用这种写法解. ...
- POJ2278 DNA Sequence —— AC自动机 + 矩阵优化
题目链接:https://vjudge.net/problem/POJ-2778 DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Tota ...
- [poj2778]DNA Sequence(AC自动机+矩阵快速幂)
题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列.(仅含A,T,C,G四个字符) 解题关键:AC自动机,实际上就是一个状态转移图,注意能少取模就少取模, ...
- poj2778 DNA Sequence(AC自动机+矩阵快速幂)
Description It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's ve ...
- hdu 2243 考研路茫茫——单词情结 AC自动机 矩阵幂次求和
题目链接 题意 给定\(N\)个词根,每个长度不超过\(5\). 问长度不超过\(L(L\lt 2^{31})\),只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个? 思路 状态(AC自动 ...
随机推荐
- Android设置对话框去除黑边
在res/values/styles.xml文件中添加如下内容 <style name="dialog" parent="@android:style/Theme. ...
- SpringMVC 学习-拦截器 HandlerInterceptor 类
一.拦截器 HandlerInterceptor 类的作用 SpringMVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理. 二.怎么使用呢? 1. ...
- JS复习第五章
第五章 引用类型 一.Object类型 创建object实例的方式有两种. 第一种是使用new操作符后跟object构造函数,如下所示: ver person = new Object( ) ; pe ...
- 高效PHP程序必知的53个技巧
用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册中说 ...
- javascript 奇淫巧技1
1.首次为变量赋值时务必使用var关键字 变量没有声明而直接赋值得话,默认会作为一个新的全局变量,要尽量避免使用全局变量. 2.使用===取代== ==和!=操作符会在需要的情况下自动转换数据类型.但 ...
- Java 反射 Method的invoke回调调用任意方法
Java 反射 Method的invoke回调调用任意方法 @author ixenos 关键子:Method.Field.invoke方法指针/函数指针.回调函数 invoke回调流程示例 0.由C ...
- 8.Hibernate的多对多关联映射
1.创建如下数据库脚本 --1.1 项目表 create table PROJECT ( proid ) not null, proname ) ) ; --1.2 项目表主键 alter table ...
- SERVICE_USE_PID
openwrt中启动脚本中经常出现如下一句: SERVICE_USE_PID=1 例如 lldp启动脚本 lldpd.init中如下: #!/bin/sh /etc/rc.common # Copyr ...
- Openjudge-计算概论(A)-角谷猜想
描述: 所谓角谷猜想,是指对于任意一个正整数,如果是奇数,则乘3加1,如果是偶数,则除以2,得到的结果再按照上述规则重复处理,最终总能够得到1.如,假定初始整数为5,计算过程分别为16.8.4.2.1 ...
- Quicksum
Quicksum Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Subm ...