已经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. 精心收集的48个JavaScript代码片段,仅需30秒就可理解

    源文链接 :https://github.com/Chalarangelo/30-seconds-of-code#anagrams-of-string-with-duplicates 该项目来自于 G ...

  2. Percona-Tookit工具包之pt-pmp

      Preface       Sometimes we need to know the details of a program(porcess) when it is running even ...

  3. ajax原生js及readystate/status

    菜鸟教程 ←← GET: <script> function  ajaxGet(){ var  xmlhttp; if(window.XMLHttpRequest){ //TE7+  Fi ...

  4. 解决.NET Core R1中文乱码问题

    今天写了一个简单的.NET Core RC1控制台程序,发现中文显示一直是乱码.查看操作系统设置,没有问题:查看源文件编码,也没有问题:甚至查看了Console字符编码相关的注册表,依然没有发现问题. ...

  5. php-5.6.26源代码 - opcode处理器,“乘法opcode”处理器

    // opcode处理器 - 运算符怎么执行: “*” 乘法opcode处理器 static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CONST_HANDLER(Z ...

  6. laravel EncryptCookies中间件导致无法获取自定义cookie

    解决办法: \app\Http\Middleware\EncryptCookies.php 添加过滤cookie key protected $except = [ 'token' ];

  7. Google Compute Engine VM自动调节

    现象:利用google云搭建VM服务,在搭建实例组有一个"自动调节"功能,可以自动添加/删除MV,当自动添加VM时可能新添加的VM就是一个新的VM,你部署的代码或者环境都没了.现在 ...

  8. php正则 与 js正则

    PHP中的正则表达式函数 在PHP中有两套正则表达式函数库.一套是由PCRE(Perl Compatible Regular Expression)库提供的.PCRE库使用和Perl相同的语法规则实现 ...

  9. QWidget 自带的最大化,最小化,关闭按键的设置

    使用函数 setWindowFlags 参数: CustomizeWindowHint 去掉窗口所有自带按钮 Qt::CustomizeWindowHint | Qt::WindowCloseButt ...

  10. 区间DP入门题目合集

      区间DP主要思想是先在小区间取得最优解,然后小区间合并时更新大区间的最优解.       基本代码: //mst(dp,0) 初始化DP数组 ;i<=n;i++) { dp[i][i]=初始 ...