poj2778(AC自动机+矩阵快速幂)
题意:给你n个字符串,问你长度为m的字符串且字符串中不含有那n个子串的字符串的数量
解题思路:这道题一开始就不太懂,还以为是组合数学的题目,后面看了别人的博客,才知道这是属于AC自动机的另一种用法,是关于fail数组的运用,因为题目问的是不允许包含那n个字符串,所以我们可以这么想,假设一个trie树每个结点都有A,T,C,G这四个儿子结点,然后我们把这n个字符串存进trie树里面,字符串的结尾标记一下,然后根据fail数组的构造,如果某个结点fail指向的结点被标记了,那么这个结点也是不允许走的,这样,一个符合条件的trie树就建立出来了,剩下的就是矩阵部分。把题目简化成是从结点0出发到其他结点走n步的的所有允许情况;
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=110;
struct matrix
{
ll mat[N][N];
matrix()
{
memset(mat,0,sizeof(mat));
}
}ans,fna;
int trie[N][4];
int fail[N],tot;
bool flag[N];
char s[15];
char c['Z'+1];
int n,m;
void build_trie(char *str)//构建trie树
{
int root=0;
int len=strlen(str);
for(int i=0;i<len;i++)
{
int id=c[str[i]];
if(trie[root][id]==0)
{
trie[root][id]=++tot;
//cout<<tot<<endl;
}
root=trie[root][id];
}
flag[root]=1;
}
void build_fail()
{
queue<int>q;
for(int i=0;i<4;i++)
{
if(trie[0][i]!=0)
q.push(trie[0][i]);
}
while(!q.empty())
{
int now=q.front();
q.pop();
if(flag[fail[now]])//如果当前结点的指向是不允许的,那么这个点也是不允许的
flag[now]=true;
for(int i=0;i<4;i++)
{
if(!trie[now][i])
{
trie[now][i]=trie[fail[now]][i];
continue;
}
fail[trie[now][i]]=trie[fail[now]][i];
q.push(trie[now][i]);
}
}
}
matrix mul(matrix x,matrix y)
{
matrix tmp;
for(int i=0;i<=tot;i++)
for(int j=0;j<=tot;j++)
for(int k=0;k<=tot;k++)
{
tmp.mat[i][j]+=x.mat[i][k]*y.mat[k][j];
tmp.mat[i][j]%=100000;
}
return tmp;
}
matrix matrixpow(matrix x,ll k)
{
matrix ret;
for(int i=0;i<=tot;i++)
ret.mat[i][i]=1;
while(k)
{
if(k&1)
ret=mul(ret,ans);
ans=mul(ans,ans);
k>>=1;
}
return ret;
}
matrix build_mat()//构建矩阵
{
matrix temp;
for(int i=0;i<=tot;i++)
{
if(flag[i])
continue;
for(int j=0;j<4;j++)
{
if(flag[trie[i][j]])continue;
++temp.mat[i][trie[i][j]];
}
}
return temp;
}
void init()
{
memset(fail,0,sizeof(fail));
memset(trie,0,sizeof(trie));
tot=0;
memset(flag,0,sizeof(flag));
c['A']=0;
c['T']=1;
c['C']=2;
c['G']=3;
}
int main()
{
init();
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{
scanf("%s",s);
build_trie(s);
}
build_fail();
ans=build_mat();
fna=matrixpow(ans,n);
ll xx=0;
for(int i=0;i<=tot;i++)
{
xx+=fna.mat[0][i];xx%=100000;
}
printf("%lld\n",xx);
}
代码:
poj2778(AC自动机+矩阵快速幂)的更多相关文章
- poj2778 ac自动机+矩阵快速幂
给m个子串,求长度为n的不包含子串的母串数,最直接的应该是暴搜,肯定tle,考虑用ac自动机 将子串建成字典树,通过next表来构造矩阵,然后用矩阵快速幂求长度为n的数量 邻接矩阵https://we ...
- POJ2778 DNA Sequence(AC自动机+矩阵快速幂)
题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个 ...
- POJ2778(SummerTrainingDay10-B AC自动机+矩阵快速幂)
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17160 Accepted: 6616 Des ...
- poj2778DNA Sequence (AC自动机+矩阵快速幂)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud DNA Sequence Time Limit: 1000MS Memory ...
- HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- HDU 2243 考研路茫茫――单词情结 ——(AC自动机+矩阵快速幂)
和前几天做的AC自动机类似. 思路简单但是代码200余行.. 假设solve_sub(i)表示长度为i的不含危险单词的总数. 最终答案为用总数(26^1+26^2+...+26^n)减去(solve_ ...
- POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂
这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...
- 考研路茫茫——单词情结 HDU - 2243 AC自动机 && 矩阵快速幂
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解
题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...
- hdu 2243 考研路茫茫——单词情结 ac自动机+矩阵快速幂
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2243 题意:给定N(1<= N < 6)个长度不超过5的词根,问长度不超过L(L <23 ...
随机推荐
- 文件类型解析漏洞防御与攻击(PHP)
简介: 解析漏洞主要是一些特殊文件被iis.Apache.Nginx等服务在某种情况下解释成脚本文件格式并得以执行而产生的漏洞,一般的思路都是用图片木马来欺骗服务器,上传webshell,达到提权的目 ...
- SAP 用户参数 ME_USE_GRID
SAP 用户参数 ME_USE_GRID SAP的一些标准报表格式极其不友好,如果不做特殊参数设定,报表使用起来很不方便.我们可以通过设置user parameter的方式,改变一些报表的显示格式,让 ...
- SAP MM MIGO & Return Delivery 组合实现部分数量的Reversal
SAP MM MIGO & Return Delivery 组合实现部分数量的Reversal 在笔者看来,MIGO这个事务代码里的Return Delivery主要用于采购退货场景. 先找到 ...
- (详细)华为荣耀V10 BKL-AL00的USB调试模式在哪里打开的步骤
每当我们使用pc连接安卓手机的时候,如果手机没有开启Usb开发者调试模式,pc则无法成功检测到我们的手机,有时我们使用的一些功能比较强的的app比如以前我们使用的一个app引号精灵,老版本就需要开启U ...
- 微信小程序(三)页面跳转和图片滑动切换
跳转部分: 在index2.wxml中,添加跳转函数,如下所示:
- Kasaraju算法--强连通图遍历及其python实现
在理解有向图和强连通分量前必须理解与其对应的两个概念,连通图(无向图)和连通分量. 连通图的定义是:如果一个图中的任何一个节点可以到达其他节点,那么它就是连通的. 例如以下图形: 这是最简单的一个连通 ...
- centos7查看可登陆用户
一.命令 cat /etc/passwd | grep -v /sbin/nologin | cut -d : -f 1 cat /etc/passwd | grep /bin/bash | cu ...
- 电信中兴F460光猫sendcmd命令
1.安装xshell后,使用命令行登陆root用户,root用户密码Zte521(湖北地区) 2.查看所有用户密码 sendcmd 1 DB p DevAuthInfo 3.打开网页登陆teleco ...
- MFC拖拽、选择目录、遍历文件
1.选择目录 void CDecryptFileDlg::OnBnClickedSel() { std::wstring selectedDir; WCHAR szDir[MAX_PATH]; Zer ...
- 我的ElasticSearch之ElasticSearch安装配置环境
最近一段时间比较忙,都很少来园子逛了,刚好,用到了ElasticSearch,感觉还不错,所以就给大家推荐一下,自己也顺便学习:虽然公司选择用ElasticSearch,但是以前都没有用过这个,而且公 ...