【AC自动机】【矩阵乘法】poj2778 DNA Sequence
http://blog.csdn.net/morgan_xww/article/details/7834801
讲得很好~可以理解自动机的本质,就是一个用来状态转移的东西~对于确定的输入而言,可以从初始状态,按照转移边,转移到确定的终止状态。
而这种转移可以用矩乘加速。
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<iostream>
using namespace std;
typedef long long ll;
#define MOD 100000ll
typedef vector<ll> vec;
typedef vector<vec> mat;
int N;
mat I,A;
mat operator * (const mat &a,const mat &b)
{
mat c(N,vec(N));
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
for(int k=0;k<N;++k)
c[i][j]=(c[i][j]+a[i][k]*b[k][j]%MOD)%MOD;
return c;
}
mat Quick_Pow(mat x,int p)
{
if(!p) return I;
mat res=Quick_Pow(x,p>>1);
res=res*res;
if(p&1) res=res*x;
return res;
}
queue<int>q;
int child[110][4],fail[110],size=1,sum,ma[1111];
bool word[110];
void Insert(char S[])
{
int len=strlen(S);
int now=0;
for(int i=0;i<len;++i)
{
if(!child[now][ma[S[i]]])
child[now][ma[S[i]]]=size++;
now=child[now][ma[S[i]]];
}
word[now]=1;
}
void build()
{
fail[0]=-1;
q.push(0);
while(!q.empty())
{
int U=q.front(); q.pop();
for(int i=0;i<4;++i)
if(child[U][i])
{
int V=fail[U];
while(V!=-1)
{
if(child[V][i])
{
fail[child[U][i]]=child[V][i];
break;
}
V=fail[V];
}
if(V==-1)
fail[child[U][i]]=0;
if(word[fail[child[U][i]]])
word[child[U][i]]=1;//如果某个单词是该结点所在单词的前缀,那么该结点也应被标记为单词结点
q.push(child[U][i]);
}
else if(U)
child[U][i]=child[fail[U]][i];//当然你在dp过程中在Trie上跳也行,但这样就避免了重复计算
//由于BFS,其实形成了一个类似链表的结构
}
}
int m,n,ma2[110];
int main()
{
// freopen("poj2778.in","r",stdin);
ma['A']=0; ma['G']=1; ma['C']=2; ma['T']=3;
char s[13];
scanf("%d%d",&m,&n);
for(int i=1;i<=m;++i)
{
scanf("%s",s);
Insert(s);
}
build();
for(int i=0;i<size;++i)
if(!word[i])
ma2[i]=N++;
I.assign(N,vec(N));
for(int i=0;i<N;++i)
I[i][i]=1;
mat A(N,vec(N));
for(int i=0;i<size;++i)
for(int j=0;j<4;++j) if((!word[i]) && (!word[child[i][j]]))
++A[ma2[i]][ma2[child[i][j]]];
// for(int i=0;i<N;++i)
// {
// for(int j=0;j<N;++j)
// printf("%d ",A[i][j]);
// puts("");
// }
A=Quick_Pow(A,n);
// for(int i=0;i<N;++i)
// {
// for(int j=0;j<N;++j)
// printf("%d ",A[i][j]);
// puts("");
// }
ll ans=0;
for(int i=0;i<N;++i)
ans=(ans+A[0][i])%MOD;
cout<<ans<<endl;
return 0;
}
【AC自动机】【矩阵乘法】poj2778 DNA Sequence的更多相关文章
- 【bzoj1444】[Jsoi2009]有趣的游戏 AC自动机+矩阵乘法
题目描述 输入 注意 是0<=P 输出 样例输入 样例输出 题解 AC自动机+矩阵乘法 先将所有字符串放到AC自动机中,求出Trie图. 然后构建邻接矩阵:如果x不是某个字符串的末位置,则x连向 ...
- DNA Sequence - POJ 2778(AC自动机+矩阵乘法)
题目大意:DNA序列是有 ATGC 组成的,现在知道一些动物的遗传片段有害的,那么如果给出这些有害的片段,能否求出来所有长度为 N 的基因中有多少是不包含这些有害片段的. 分析:也是断断续续做了一 ...
- POJ 2778 DNA Sequence (AC自动机,矩阵乘法)
题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...
- 【POJ2778】AC自动机+矩阵乘法
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14758 Accepted: 5716 Descrip ...
- 【poj2778-DNA Sequence】AC自动机+矩阵乘法
题意: (只含AGCT)给定m个病毒串,让你构造一个长度为n的字符串(也只含有AGCT),问有多少种方案.n很大:1<=n<=2000000000 题解: 用病毒串建立AC自动机(num个 ...
- POJ 2778 (AC自动机+矩阵乘法)
POJ 2778 DNA Sequence Problem : 给m个只含有(A,G,C,T)的模式串(m <= 10, len <=10), 询问所有长度为n的只含有(A,G,C,T)的 ...
- [BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】
题目链接:BZOJ - 1009 题目分析 题目要求求出不包含给定字符串的长度为 n 的字符串的数量. 既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j ...
- hdu2243之AC自动机+矩阵乘法
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- bzoj 2553: [BeiJing2011]禁忌 AC自动机+矩阵乘法
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2553 题解: 利用AC自动机的dp求出所有的转移 然后将所有的转移储存到矩阵中,进行矩阵 ...
- BZOJ 1009 GT考试 (AC自动机 + 矩阵乘法加速dp)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1009 题意: 准考证号为\(n\)位数\(X_1X_2....X_n(0<=X_ ...
随机推荐
- CSS3边框会动的信封
<!DOCTYPE html><html> <head> <title>酷炫的CSS3</title> <meta charset=& ...
- HDU 多校对抗赛 A Maximum Multiple
Maximum Multiple Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- oracle数据库cmd导出数据和导入数据
一:前言 每次我自己来导出oracle数据的数据进行备份的时候都是要看一遍记载的语句,还别说自己敲多了,也熟练了,但是还是不是很放心,所以就记载下来吧. 二:内容 (1).最简单,最直接的导入方式(这 ...
- 给 ecplise 配置struts2配置环境
下面介绍在Eclipse中配置Struts2的过程: 一.下载Struts2,因为Struts2是开源的,百度或者google一下就可以找到下载地址.我下载的是struts-2.3.1.2版本 的,解 ...
- 【uva11019-Matrix Matcher】AC自动机+优化+记录
http://acm.hust.edu.cn/vjudge/problem/33057 题意:在二维文本串T中查找一个二维模板串P出现了多少次. 题解: 拆分模板串P的每一行,建AC自动机.拆分文本串 ...
- 在Xcode5下实现4.5,4.6的效果
https://www.evernote.com/shard/s227/sh/a575caee-d6a8-4f43-9037-145b9a6913ca/c9a2befa22ce7c3f547f58 ...
- 【洛谷 P2464】[SDOI2008]郁闷的小J(线段树)
题目链接 这题我很久之前用分块写过,没写出来.. 今天又看到了,于是下决心把这题做出来. 这次我用线段树写的,直接对每本书的编号Hash一下然后离散化然后各建一棵线段树,维护当前编号在某个位置有没有书 ...
- 卡片选项页面 JTabbedPane 的使用
package first; import javax.swing.*; import java.awt.*; import java.awt.event.*; class TtpDemo exten ...
- mybatis注解动态sql
@Insert("INSERT INTO user (name, age, gender, experience) VALUES (<a href="http://www.o ...
- 类的 propert,classmethod,ataticmethod 方法 与 多态
一 .property 将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数 然后计算出来的,这种特性的使用方式遵循了统一访问的原则 egon. ...