【题目链接】 http://poj.org/problem?id=2778

【题目大意】

  给出一些字符串,求不包含这些字符串的长度为n的字符串的数量

【题解】

  我们将所有串插入自动机计算match,对于自动机上所有节点构建转移矩阵,
  对于得到的可达矩阵我们求n长路的数量,统计0到各个点的n长路之和就是答案。

【代码】

#include <cstdio>
#include <cstring>
using namespace std;
const int N=110;
typedef long long LL;
LL P=100000LL;
struct mat{
int n;
LL num[110][110];
void init0(int t){
n=t;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
num[i][j]=0;
}
void init1(int t){
n=t;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i!=j)num[i][j]=0;else num[i][j]=1;
}
mat operator = (const struct mat p){
n=p.n;
for(int i=0;i<n;i++)for(int j=0;j<n;j++)num[i][j]=p.num[i][j];
}
mat operator * (const struct mat p)const{
struct mat ans;
ans.init0(n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
ans.num[i][j]=(ans.num[i][j]+num[i][k]*p.num[k][j])%P;
return ans;
}
mat operator ^(int t)const{
struct mat ans,now;
ans.init1(n);
now.n=n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
now.num[i][j]=num[i][j];
while(t>0){
if(t&1)ans=ans*now;
now=now*now;
t>>=1;
}return ans;
}
}mat;
namespace AC_DFA{
const int Csize=4;
int tot,son[N][Csize],sum[N],fail[N],q[N],ans[N],match[N];
void Initialize(){
memset(sum,0,sizeof(int)*(tot+1));
memset(ans,0,sizeof(int)*(tot+1));
memset(match,0,sizeof(int)*(tot+1));
memset(fail,0,sizeof(int)*(tot+1));
for(int i=0;i<=tot;i++)for(int j=0;j<Csize;j++)son[i][j]=0;
tot=0; fail[0]=-1;
}
inline int Tr(char ch){
if(ch=='A')return 0;
if(ch=='T')return 1;
if(ch=='C')return 2;
if(ch=='G')return 3;
}
int Insert(char *s){
int x=0;
for(int l=strlen(s),i=0,w;i<l;i++){
if(!son[x][w=Tr(s[i])]){
son[x][w]=++tot;
}x=son[x][w];
}sum[x]++;
return x;
}
void MakeFail(){
int h=1,t=0,i,j,x=0;
for(i=0;i<Csize;i++)if(son[0][i]){
q[++t]=son[0][i];
match[son[0][i]]=sum[son[0][i]]?son[0][i]:match[fail[son[0][i]]];
}
while(h<=t)for(x=q[h++],i=0;i<Csize;i++)
if(son[x][i]){
fail[son[x][i]]=son[fail[x]][i],q[++t]=son[x][i];
match[son[x][i]]=sum[son[x][i]]?son[x][i]:match[fail[son[x][i]]];
}else son[x][i]=son[fail[x]][i];
}
}
using namespace AC_DFA;
char s[20];
void BuildMat(){
mat.init0(tot+1);
for(int i=0;i<=tot;i++){
if(match[i])continue;
for(int j=0;j<Csize;j++){
if(!match[son[i][j]])mat.num[i][son[i][j]]++;
}
}
}
int n,m;
int main(){
while(~scanf("%d%d",&m,&n)){
Initialize();
while(m--){scanf("%s",s);Insert(s);}
MakeFail(); BuildMat();
mat=mat^n; int ans=0;
for(int i=0;i<mat.n;i++)ans=(ans+mat.num[0][i])%P;
printf("%d\n",ans);
}return 0;
}

POJ 2778 DNA Sequence(AC自动机+矩阵)的更多相关文章

  1. poj 2778 DNA Sequence ac自动机+矩阵快速幂

    链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...

  2. POJ 2778 DNA Sequence (AC自动机,矩阵乘法)

    题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...

  3. poj 2778 DNA Sequence AC自动机DP 矩阵优化

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

  4. POJ 2778 DNA Sequence ( AC自动机、Trie图、矩阵快速幂、DP )

    题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析 : 这题搞了我真特么久啊,首先你需要知道的前置技能包括 AC自动机.构建Trie图.矩阵快速幂,其中矩 ...

  5. poj 2778 DNA Sequence AC自动机

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

  6. POJ 2778 DNA Sequence (AC自动机+DP+矩阵)

    题意:给定一些串,然后让你构造出一个长度为 m 的串,并且不包含以上串,问你有多少个. 析:很明显,如果 m 小的话 ,直接可以用DP来解决,但是 m 太大了,我们可以认为是在AC自动机图中,根据离散 ...

  7. POJ2278 DNA Sequence —— AC自动机 + 矩阵优化

    题目链接:https://vjudge.net/problem/POJ-2778 DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Tota ...

  8. POJ 2778 DNA Sequence (AC自己主动机 + dp)

    DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...

  9. [poj2778]DNA Sequence(AC自动机+矩阵快速幂)

    题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列.(仅含A,T,C,G四个字符) 解题关键:AC自动机,实际上就是一个状态转移图,注意能少取模就少取模, ...

  10. POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂

    这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...

随机推荐

  1. APScheduler API -- apscheduler.triggers.date

    apscheduler.triggers.date API Trigger alias for add_job(): date class apscheduler.triggers.date.Date ...

  2. 【算法学习】有旋treap

    treap是平衡树的一种.与其他平衡树一样,它也能够支持插入和删除,求第k极值等,接下来我们主要探讨有旋treap的实现过程. treap中每个节点要维护其值,左右孩子以及子树大小.父亲要不要写则看你 ...

  3. 【CTF MISC】pyc文件反编译到Python源码-2017世安杯CTF writeup详解

    1.题目 Create-By-SimpleLab 适合作为桌面的图片 首先是一张图片,然后用StegSolve进行分析,发现二维码 扫码得到一串字符 03F30D0A79CB0558630000000 ...

  4. Android Framebuffer介绍及使用【转】

    转自:https://www.jianshu.com/p/df1213e5a0ed 来自: Android技术特工队 作者: Aaron 主页: http://www.wxtlife.com/ 原文连 ...

  5. js中字符串的常用方法

    一.普通方法 1.字符方法 动态方法:1.str.charAt(index);  返回子字符串,index为字符串下标,index取值范围[0,str.length-1] 动态方法:2.str.cha ...

  6. idea心得

    概述 Intellij IDEA真是越用越觉得它强大,它总是在我们写代码的时候,不时给我们来个小惊喜.出于对Intellij IDEA的喜爱,我决定写一个与其相关的专栏或者系列,把一些好用的Intel ...

  7. php 的swoole 和websocket 连接wss

    1. 下载证书 $serv = new swoole_server('0.0.0.0', 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); $s ...

  8. springMVC源码分析--HttpMessageConverter数据转化(一)

    之前的博客我们已经介绍了很多springMVC相关的模块,接下来我们介绍一下springMVC在获取参数和返回结果值方面的处理.虽然在之前的博客老田已经分别介绍了参数处理器和返回值处理器: (1)sp ...

  9. COLLATE CHINESE_PRC_CI_AS_WS 的含义

    排序规则:COLLATE CHINESE_PRC_CI_AS_WS 的含义 在创建数据表时,常会用到这个. 含义当中,CHINESE_prc_ 是代表中国大陆.如果是台湾,则如:Chinese_TAI ...

  10. Spring Boot整合JPA、Redis和Swagger2

    好久没有总结了,最近也一直在学习.今天就把spring boot与其它技术的整合做个小总结,主要是jpa.redis和swagger2.公司里有用到这些,整合起来也很简单. 首先,新建一个Spring ...