【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)
已经128天了?怎么觉得上次倒计时150天的日子还很近啊
....好吧为了把AC自动机搞透我也是蛮拼的..把1030和这道题对比了无数遍...最终结论是...无视时间复杂度,1030可以用这种写法解..但是!!对于26个字母的就算了吧...
其实这道题体现的是一个对于AC自动机等价态,即fail的表示和处理上:
通常有两种方法处理等价态,第一是互为等价态的点各自记录各自的信息。匹配的时候需要遍历所有等价态以判断是否匹配成功。next指针可能为空,需要匹配时进行判断是否需要走fail指针。
第二是所有等价态中的点记录本身以及所有比它浅的点的信息总和(匹配成功的单词总数),匹配时不需要走等价态以判断匹配成功与否。next指针不为空,直接指向本应通过fail指针寻找到的那个状态。我的新的模版就是用的这种方式...因为这样感觉好写而且也快...
然后这道题,我们把AC自动机看成一个有向图,这样用mat[i,j]表示由节点i到节点j上有一条路...这个矩阵的n次幂表示从i恰好走n步到达j的路径有几条...大概是这样
然后我又TLE了..
const
maxn=;
maxs=;
vv=;
type
mattype=record
n,m:longint;
a:array[..,..] of longint;
end;
rectype=array[..] of longint;
var
next:array[..maxn,..maxs] of longint;
pd:array[..maxn] of boolean;
q,f:array[..maxn] of longint;
ori:mattype;
n,m,tot,head,tail,root:longint; procedure push(x:longint); begin inc(tail); q[tail]:=x; end; operator *(x,y:mattype)tmp:mattype;
var i,j,k:longint;
begin
tmp.n:=x.n; tmp.m:=y.m;
fillchar(tmp.a,sizeof(tmp.a),);
for i:= to tmp.n do
for j:= to tmp .m do
for k:= to x.m do
tmp.a[i,j]:=(tmp.a[i,j]+int64(x.a[i,k])*y.a[k,j] mod vv) mod vv;
exit(tmp);
end; function pow(x:mattype;k:longint):mattype;
var tmp:mattype; i:longint;
begin
tmp.n:=x.n; tmp.m:=x.n;
fillchar(tmp.a,sizeof(tmp.a),);
for i:= to x.n do tmp.a[i,i]:=;
while k> do
begin
if (k and )= then tmp:=tmp*x;
x:=x*x;
k:=k>>;
end;
exit(tmp);
end; function new:longint;
var i:longint;
begin
pd[tot]:=false;
for i:= to maxs do next[tot,i]:=-;
inc(tot); exit(tot-);
end; procedure insert(s:rectype);
var i,c,v:longint;
begin
v:=root;
for i:= to s[] do
begin
c:=s[i];
if next[v,c]=- then next[v,c]:=new;
v:=next[v,c];
end;
pd[v]:=true;
end; procedure build;
var i,v:longint;
begin
f[root]:=root;
head:=; tail:=;
for i:= to maxs do
if next[root,i]=- then next[root,i]:=root
else begin f[next[root,i]]:=root; push(next[root,i]); end;
while head<=tail do
begin
v:=q[head]; inc(head);
if pd[f[v]] then pd[v]:=true;
for i:= to maxs do
if next[v,i]=- then next[v,i]:=next[f[v],i]
else begin f[next[v,i]]:=next[f[v],i]; push(next[v,i]); end;
end;
end; function change(c:char):longint;
begin
case c of
'A': exit();
'C': exit();
'G': exit();
'T': exit();
end;
end; procedure init;
var ss:string;
s:rectype;
i,j:longint;
begin
tot:=;
root:=new;
readln(n,m);
for i:= to n do
begin
readln(ss);
s[]:=length(ss);
for j:= to s[] do s[j]:=change(ss[j]);
insert(s);
end;
dec(tot);
build;
ori.n:=tot; ori.m:=tot;
for i:= root to tot do
for j:= to maxs do
if not pd[next[i,j]] then inc(ori.a[i,next[i,j]]);
end; procedure solve;
var ans,i:longint;
begin
ori:=pow(ori,m);
ans:=;
for i:= to ori.n do ans:=(ans+ori.a[,i]) mod vv;
writeln(ans);
end; Begin
init;
solve;
End.
【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)的更多相关文章
- poj2778 DNA Sequence(AC自动机+矩阵快速幂)
Description It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's ve ...
- POJ2778 DNA Sequence(AC自动机 矩阵)
先使用AC自动机求得状态转移关系,再建立矩阵,mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数,则此矩阵的n次方表示n步从i,到j的方法数. #include<cstdio& ...
- [poj2778]DNA Sequence(AC自动机+矩阵快速幂)
题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列.(仅含A,T,C,G四个字符) 解题关键:AC自动机,实际上就是一个状态转移图,注意能少取模就少取模, ...
- POJ2278 DNA Sequence —— AC自动机 + 矩阵优化
题目链接:https://vjudge.net/problem/POJ-2778 DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Tota ...
- [poj2778 DNA Sequence]AC自动机,矩阵快速幂
题意:给一些字符串的集合S和整数n,求满足 长度为n 只含charset = {'A'.'T‘.'G'.'C'}包含的字符 不包含S中任一字符串 的字符串的种类数. 思路:首先对S建立ac自动机,考虑 ...
- poj 2778 DNA Sequence ac自动机+矩阵快速幂
链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...
- POJ 2778 DNA Sequence (AC自动机,矩阵乘法)
题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...
- POJ 2778 DNA Sequence(AC自动机+矩阵加速)
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9899 Accepted: 3717 Desc ...
- poj 2778 DNA Sequence AC自动机
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11860 Accepted: 4527 Des ...
随机推荐
- P2661 信息传递 DFS
题目链接:洛谷 P2661 信息传递 一个人要想知道自己的生日,就意味着信息的传递是成环的,因为每轮信息只能传递一个人,传递的轮数就等于环的大小 环的大小就等于环中的两个点到第三个点的距离之和加一,我 ...
- 异构数据库迁移——DATAX
背景 在最近接触到的一个case里面,需要把db2的数据迁移至oracle,客户可接收的停机时间为3小时. 同步方式的比较 一说到停机时间,大家第一时间想到Oracle公司的GoldenGate实时同 ...
- Thinkphp 取消Url默认模块的现实
例子http://www.tp.com/home/index/index 想要现实的效果是:http://www.tp.com/index/index 1是通过配置路由来达到目的 2通过配置首页的入口 ...
- Android内购订单验证 --- php实现
直接上代码: function googleVerify($sdata,$google_public_key) { $sdata = json_decode($sdata,true); $in_app ...
- MyCat实现数据库与数据库之间的读写分离
一.Mycat的安装准备: 1.jdk:要求jdk必须是1.7及以上版本 2.Mysql:推荐mysql是5.5以上版本 3.Mycat: Mycat的官方网站: http://www.mycat.o ...
- 学习Pytbon第九天,函数1 过程和参数
函数def func1():定义函数 '''testing1'''#函数的说明 print("in the func1")#定义过程 return 0 #得到函数的执行结果.还是程 ...
- A Country on Wheels【车轮上的国家】
A Country on Wheels As cultural symbols go, the American car is quite young. 作为文化象征的美国汽车还相当年轻. The ...
- C++基础 const
1. C中的const C中const变量只是只读变量,有自己存储空间.可能被存放在 栈.堆.数据段,所以可以修改. 2. C++中const 可能分配空间,也可能不分配空间. 当 const 为全局 ...
- centos安装xfce及输入法
一.执行CentOS7 最小安装 去官网 https://www.centos.org/ 下载CentOS-7-x86_64-Minimal-1804.iso,然后使用rufus刻录U盘,安装之.安装 ...
- java线程安全(单例模式)(转载)
原文链接:http://www.jameswxx.com/java/%E8%AF%B4%E8%AF%B4%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/ 单例模式?多么简单! ...