题目链接:点击查看

题目大意:给出 n 个长度不大于 10 的字符串表示病毒串,再给出一个长度 len ,问长度为 len 的字符串中,有多少个字符串不含有病毒串作为子串

题目分析:因为病毒串的长度和数量均不大于 10 ,所以我们对病毒串构造AC自动机后会有最多 100 个结点代表 100 个状态,注意对病毒串的标记,在构造AC自动机时记得把标记下传,因为某个节点如果是病毒串的话,那么含有该前缀的后缀一定也是不可行的,我们可以对于这 100 个状态构造矩阵,表示每个状态到另一个状态可行的方案数,最后利用快速幂求解就行了,对于这类题目而言还有一个地方不太明白,但网上的博客也都没说明白,先当结论记着吧,就是为什么构造出的矩阵自乘 n 次后就是长度为 n 的字符串的可行方案数,也怪我自己上个学期的线性代数没有学好,矩阵乘法或许有特殊的意义吧

对于这个题目而言还有一个细节,如果直接按照普通的矩阵快速幂模板写的话会超时,因为每次都需要取模,也是这个题我才知道取模原来还是有时间代价的,我们可以减少取模次数以达到加速的效果

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=110;const int mod=100000; char s[N];int fail[N],trie[N][4],id[150],cnt;bool vis[N];struct Ma
{LL a[N][N];Ma(){memset(a,0,sizeof(a));}Ma operator*(const Ma& b)const{Ma ans;for(int i=0;i<=cnt;i++)for(int j=0;j<=cnt;j++){for(int k=0;k<=cnt;k++)ans.a[i][j]+=a[i][k]*b.a[k][j];ans.a[i][j]%=mod;}return ans;}
}maze;Ma q_pow(Ma a,LL b)//矩阵快速幂
{Ma ans;for(int i=0;i<=cnt;i++)ans.a[i][i]=1;while(b){if(b&1)ans=ans*a;a=a*a;b>>=1;}return ans;
}void getmaze()
{memset(maze.a,0,sizeof(maze.a));for(int i=0;i<=cnt;i++)if(!vis[i])for(int j=0;j<4;j++)if(!vis[trie[i][j]])maze.a[i][trie[i][j]]++;
}void insert_word()
{int len=strlen(s);int pos=0;for(int i=0;i<len;i++){int to=id[s[i]];if(!trie[pos][to])trie[pos][to]=++cnt;pos=trie[pos][to];}vis[pos]=true;
}void getfail()
{queue<int>q;for(int i=0;i<4;i++){if(trie[0][i]){fail[trie[0][i]]=0;q.push(trie[0][i]);}}while(!q.empty()){int cur=q.front();q.pop();if(vis[fail[cur]])vis[cur]=true;for(int i=0;i<4;i++){if(trie[cur][i]){fail[trie[cur][i]]=trie[fail[cur]][i];q.push(trie[cur][i]);}elsetrie[cur][i]=trie[fail[cur]][i];}}
}void init()
{cnt=0;memset(vis,false,sizeof(vis));memset(trie,0,sizeof(trie));id['A']=0,id['C']=1,id['G']=2,id['T']=3;
}int main()
{
//#ifndef ONLINE_JUDGE
//  freopen("input.txt","r",stdin);
//#endif
//  ios::sync_with_stdio(false);int n,m;while(scanf("%d%d",&n,&m)!=EOF){init();while(n--){scanf("%s",s);insert_word();}getfail();getmaze();maze=q_pow(maze,m);int ans=0;for(int i=0;i<=cnt;i++)ans=(ans+maze.a[0][i])%mod;printf("%d\n",ans);}return 0;
}

POJ - 2778 DNA Sequence(AC自动机+矩阵快速幂)相关推荐

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

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

  2. poj2778DNA Sequence (AC自动机+矩阵快速幂)

    转载请注明出处: http://www.cnblogs.com/fraud/           --by fraud DNA Sequence Time Limit: 1000MS   Memory ...

  3. 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 ...

  4. poj 2778 AC自动机+矩阵快速幂

    题目链接:https://vjudge.net/problem/POJ-2778 题意:输入n和m表示n个病毒,和一个长为m的字符串,里面只可以有'A','C','G','T' 这四个字符,现在问这个 ...

  5. HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)

    背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...

  6. HDU - 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)

    题目链接:点击查看 题目大意:给出 n 个词根,现在要求出长度不大于 len 的单词中,有多少单词包含至少一个词根 题目分析:如果我们反过来想,也就是求出来总的单词数,然后减去不包含词根的单词数,剩下 ...

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

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

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

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

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

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

最新文章

  1. ulua/tolua中timer.lua和event.lua的使用(Luaframework)
  2. 怎么创建计算机快捷方式到桌面两种方法,使用脚本主机创建Windows快捷方式 - Windows Client | Microsoft Docs...
  3. 10分钟 MySQL 入门教程
  4. 怎么撤销定时说说_武夷山币7省线下预约火爆!名字错了怎么办,附预约问题整理...
  5. FPGA实现VGA显示(二)——————color_bar显示及方框移动(参考开拓者FPGA开发指南)
  6. 大数据系列2-liunx基础-1操作系统介绍
  7. python字典由键插值_SciPyTutorial-一元插值interp1d
  8. opencv 写视频时找不到编码器问题解决方法
  9. open and openat
  10. php执行js加密解密
  11. 安徽新华学院计算机学院官网,安徽新华学院计算机协会第十八届换届大会
  12. python 打开网页并截图_python实现自动网页截图并裁剪图片
  13. 研究生复试英语问答口语10个最可能问到的问题
  14. #基本概念# 随机试验 / 样本空间 / 随机变量
  15. 深度学习入门 (九):卷积层和池化层的实现
  16. 用计算机用u盘怎么切换,u盘上的东西换个电脑就不见了怎么办啊
  17. EasyExcel实现下载Excel(解决无法从浏览器下载问题)
  18. 深度学习利器之自动微分(2)
  19. 50 道 Python 基础练习题(附答案详解)
  20. 身体指数bmi流程图_BMI指数事关重大,你家娃合不合格赶紧来对表查!

热门文章

  1. 状态码202_HTTP状态码大全
  2. 完成登录并生成JWT
  3. Maven的依赖管理
  4. 百万数据报表读取:步骤分析以及自定义事件处理器
  5. sqoop导入-hdfs
  6. ReactJS入门之生命周期
  7. 方法的重写-覆盖父类方法,重写子类方法实现
  8. java文件中有中文,在windows下因编码不一致,而导致编译失败的处理方法。
  9. 解决 Tomcat 下 getInitParameter 返回 null
  10. 【项目经验】在填写表单时,首先添加一个失去焦点事件,将数据库中信息自动填充信息到表单,其余信息手动填写然后提交表单。