已经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自动机+矩阵加速)的更多相关文章

  1. 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 ...

  2. POJ2778 DNA Sequence(AC自动机 矩阵)

    先使用AC自动机求得状态转移关系,再建立矩阵,mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数,则此矩阵的n次方表示n步从i,到j的方法数. #include<cstdio& ...

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

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

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

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

  5. [poj2778 DNA Sequence]AC自动机,矩阵快速幂

    题意:给一些字符串的集合S和整数n,求满足 长度为n 只含charset = {'A'.'T‘.'G'.'C'}包含的字符 不包含S中任一字符串 的字符串的种类数. 思路:首先对S建立ac自动机,考虑 ...

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

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

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

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

  8. POJ 2778 DNA Sequence(AC自动机+矩阵加速)

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9899   Accepted: 3717 Desc ...

  9. poj 2778 DNA Sequence AC自动机

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

随机推荐

  1. Aspects– iOS的AOP面向切面编程的库

    简介 一个简洁高效的用于使iOS支持AOP面向切面编程的库.它可以帮助你在不改变一个类或类实例的代码的前提下,有效更改类的行为.比iOS传统的 AOP方法,更加简单高效.支持在方法执行的前/后或替代原 ...

  2. poj_1284_Primitive root

    We say that integer x, 0 < x < p, is a primitive root modulo odd prime p if and only if the se ...

  3. JS - 简单的下载图片至本地

    <iframe id="saveImg" src="图片路径" style="display:none;"></ifram ...

  4. VM虚拟机里的Ubuntu系统怎么设置屏幕分辨率

    说白了就是安装VMWare tools工具,步骤如下: 1)在VMWare中启动ubuntu虚拟机 2)在VMWare中:右键单击启动虚拟机,点击[安装vmware tools] 3)在ubuntu中 ...

  5. PHP使用redis(一)

    1,connect 描述:实例连接到一个Redis.参数:host: string,port: int返回值:BOOL 成功返回:TRUE;失败返回:FALSE <?php  $redis = ...

  6. 创建数据库配置文件ini(转)

    一.有必要了解INI文件的结构: ;注释 [小节名] 关键字=值 ... ---- INI文件允许有多个小节,每个小节又允许有多个关键字, “=”后面是该关键字的值. ---- 值的类型有三种:字符串 ...

  7. delphi的消息对话框

    delphi的消息对话框,类似VFP中的WAIT和MESSAGEBOXdelphi的消息对话框,类似VFP中的WAIT和MESSAGEBOX1.最简单的是:showmessage() 它只有一个OK按 ...

  8. python中全局变量和局部变量

    例1: a = 100 #定义全局变量a def test1(): print(a) #此处a为全局变量 def test2(a):#此处a为局部变量 print(a)#此处a为局部变量 test1( ...

  9. sigaction函数

    sigaction函数是设置信号处理的接口.比signal函数更健壮 #include <signal.h> int sigaction(int signum, const struct ...

  10. POJ:2739-Sum of Consecutive Prime Numbers(尺取)

    Sum of Consecutive Prime Numbers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 27853 Ac ...