poj2778 AC自动机
以下内容均为转载,,只有代码是自己写的=-=
http://blog.csdn.net/morgan_xww/article/details/7834801 转载地址 博主写的很好
---------------------------------------------------------------------------------------我是分割线
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 16585 | Accepted: 6408 |
Description
Suppose that DNA sequences of a species is a sequence that consist of A, C, T and G,and the length of sequences is a given integer n.
Input
Next m lines each line contain a DNA genetic disease segment, and length of these segments is not larger than 10.
Output
Sample Input
4 3
AT
AC
AG
AA
Sample Output
36

2 1 0 0 1
2 1 1 0 0
1 1 0 1 1
2 1 0 0 1
2 1 0 0 1
M[i,j]表示从结点i到j只走一步有几种走法。
那么M的n次幂就表示从结点i到j走n步有几种走法。
注意:危险结点要去掉,也就是去掉危险结点的行和列。结点3和4是单词结尾所以危险,结点2的fail指针指向4,当匹配”AC”时也就匹配了”C”,所以2也是危险的。
矩阵变成M:
2 1
2 1
计算M[][]的n次幂,然后 Σ(M[0,i]) mod 100000 就是答案。
由于n很大,可以使用二分来计算矩阵的幂
#include<cstdio>
#include<map>
#include<queue>
#include<cstring>
#include<algorithm>
typedef long long ll;
using namespace std;
const int N=101;
const int mod=1e5;
struct Mat
{
ll mat[N][N];
Mat operator *(const Mat &B)const
{
Mat C;
memset(C.mat,0,sizeof(C.mat));
for(int k=0; k<N; ++k)
{
for(int i=0; i<N; ++i)
{
if(mat[i][k]==0) continue;
for(int j=0; j<N; ++j)
{
if(B.mat[k][j]==0) continue;
C.mat[i][j]=(C.mat[i][j]+mat[i][k]*B.mat[k][j])%mod;
}
}
}
return C;
}
int operator ^(int &k)
{
Mat C;
memset(C.mat,0,sizeof(C.mat));
for(int i=0; i<N; ++i)
C.mat[i][i]=1;
while(k)
{
if(k&1)
{
C=C*(*this);
--k;
}
k>>=1;
(*this)=(*this)*(*this);
}
int cnt=0;
for(int i=0; i<N; ++i)
cnt=(cnt+C.mat[0][i])%mod;
return cnt;
}
};
struct AC{
int ch[58][4],fail[58],val[58],sz,rt,id[128];
void init(){
sz=rt=0;
memset(ch[rt],-1,sizeof(ch[rt]));
id['A']=0,id['G']=1,id['T']=2,id['C']=3;
}
void insert(char *str){
int u=rt,len=strlen(str);
for(int i=0;i<len;++i){
int op=id[str[i]];
if(ch[u][op]==-1) {
++sz;
memset(ch[sz],-1,sizeof(ch[sz]));
val[sz]=0;
ch[u][op]=sz;
}
u=ch[u][op];
}
val[u]=1;
}
void build(){
queue<int>Q;
int u=rt;
for(int i=0;i<4;++i){
if(ch[u][i]==-1) ch[u][i]=rt;
else {
fail[ch[u][i]]=rt;
Q.push(ch[u][i]);
}
}
while(!Q.empty()){
u=Q.front();
Q.pop();
val[u]|=val[fail[u]];
for(int i=0;i<4;++i){
if(ch[u][i]==-1) ch[u][i]=ch[fail[u]][i];
else {
fail[ch[u][i]]=ch[fail[u]][i];
Q.push(ch[u][i]);
}
}
}
}
void work(int n){
Mat A;
memset(A.mat,0,sizeof(A.mat));
for(int i=0;i<=sz;++i)
for(int j=0;j<4;++j)
if(!val[ch[i][j]]) ++A.mat[i][ch[i][j]];
printf("%d\n",A^n);
}
}ac;
char s[55];
int main(){
int m,n;
while(scanf("%d%d",&m,&n)!=EOF){
ac.init();
while(m--){
scanf("%s",s);
ac.insert(s);
}
ac.build();
ac.work(n);
}
}
poj2778 AC自动机的更多相关文章
- poj2778 ac自动机+矩阵快速幂
给m个子串,求长度为n的不包含子串的母串数,最直接的应该是暴搜,肯定tle,考虑用ac自动机 将子串建成字典树,通过next表来构造矩阵,然后用矩阵快速幂求长度为n的数量 邻接矩阵https://we ...
- 【POJ2778】DNA Sequence(AC自动机,DP)
题意: 生物课上我们学到,DNA序列中只有A, C, T和G四种片段. 经科学发现,DNA序列中,包含某些片段会产生不好的基因,如片段"ATC"是不好片段,则"AGATC ...
- 【POJ2778】AC自动机+矩阵乘法
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14758 Accepted: 5716 Descrip ...
- poj2778(AC 自动机)
poj2778 题意 构造只包含 \(A, T, C, G\) 的字符串,且满足不出现指定的一些字符串,问长度为 \(n\) 的字符串有多少种 ? 分析 AC 自动机 + 矩阵快速幂的神题 ,知识点很 ...
- POJ2778 DNA Sequence(AC自动机 矩阵)
先使用AC自动机求得状态转移关系,再建立矩阵,mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数,则此矩阵的n次方表示n步从i,到j的方法数. #include<cstdio& ...
- POJ2778 DNA Sequence(AC自动机+矩阵快速幂)
题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个 ...
- poj2778(AC自动机+矩阵快速幂)
题意:给你n个字符串,问你长度为m的字符串且字符串中不含有那n个子串的字符串的数量 解题思路:这道题一开始就不太懂,还以为是组合数学的题目,后面看了别人的博客,才知道这是属于AC自动机的另一种用法,是 ...
- 【POJ2778】DNA Sequence 【AC自动机,dp,矩阵快速幂】
题意 题目给出m(m<=10)个仅仅由A,T,C,G组成的单词(单词长度不超过10),然后给出一个整数n(n<=2000000000),问你用这四个字母组成一个长度为n的长文本,有多少种组 ...
- poj2778 DNA Sequence【AC自动机】【矩阵快速幂】
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19991 Accepted: 7603 Des ...
随机推荐
- Scala教程之:可扩展的scala
文章目录 隐式类 限制条件 字符串插值 s 字符串插值器 f 插值器 raw 插值器 自定义插值器 Scala是扩展的,Scala提供了一种独特的语言机制来实现这种功能: 隐式类: 允许给已有的类型添 ...
- 在线教育项目-day05【课程分类管理-添加课程分类】
1.引入依赖 之前测试EasyExcel已经引入过了 2.利用代码生成器生成结构 我们做的只需要更改代码生成器的数据库表即可 3.运行代码生成器 4.书写代码 1.controller @RestCo ...
- 1309:【例1.6】回文数(Noip1999)
传送门:http://ybt.ssoier.cn:8088/problem_show.php?pid=1309 [题目描述] 若一个数(首位不为零)从左向右读与从右向左读都是一样,我们就将其称之为回文 ...
- Binary Index Tree
0 引言 Leetcode307 这道题给一个可变数组,求从\(i\)到\(j\)的元素之和. 一个naive的做法是,每次查询都从\(i\)累加到\(j\): class NumArray { pu ...
- POJ 1170 Shopping Offers非状态压缩做法
Shopping Offers Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5659 Accepted: 2361 Descr ...
- java的Timer定时器任务
在项目开发中,经常会遇到需要实现一些定时操作的任务,写过很多遍了,然而每次写的时候,总是会对一些细节有所遗忘,后来想想可能是没有总结的缘故,所以今天小编就打算总结一下可能会被遗忘的小点: 1. pub ...
- nginx代理路径配置总结
一.发现问题 配置nginx代理的时候,发现location配置的路径和代理的上下文路径的组合不同,服务端接收到的uri的路径不同,导致了controller的RequestMapping匹配出现问题 ...
- ubuntu18.04下mysql安装时没有出现密码提示
前言: 一:配置 ubuntu 18.04 mysql 5.7.30 二:问题 ubuntu18.04下mysql安装时没有出现密码提示,安装后自己有一个默认的用户名以及密码 解决方案: 1. 在终端 ...
- 【Hadoop离线基础总结】Hue与Hadoop集成
目录 1.更改所有hadoop节点的core-site.xml配置 2.更改所有hadoop节点的hdfs-site.xml 3.重启hadoop集群 4.停止hue的服务,并继续配置hue.ini ...
- 【Hadoop离线基础总结】完全分布式环境搭建
完全分布式环境搭建 服务规划 适用于工作当中正式环境搭建 安装步骤 第一步:安装包解压 停止之前的Hadoop集群的所有服务,并删除所有机器的Hadoop安装包,然后重新解压Hadoop压缩包 三台机 ...