洛谷题目传送门

AC自动机入门——yyb巨佬的博客

AC自动机入手经典好题(虽然年代久远)

有了fail指针,trie树就不是原来的树型结构了,我们可以把它叫做trie图,由父节点向子节点连的边和fail代表的边构成(都是单向边)。

最模板的AC自动机,就是直接匹配字符串。然而这题思维并非如此简单。

来一波逆向思维。假设我们构造出了一个无限长的安全代码,再拿到AC自动机上匹配,会发生什么?

没错,当我们一位一位地匹配的时候,我们会发现,永远都不会跳到某个病毒代码段结尾的位置(以后把这里称作危险节点,因为匹配到此处表明已经出现了某个病毒代码段),然后似乎会在自动机里永无止境地打转转。。。。。。

既然这个自动机又像一个图,那我们的问题不就变成了——在AC自动机(trie图)中寻找一个环,并且环上没有任何危险节点,并且还要注意,这个环能被根节点访问到(也就是说从根节点出发能在不经过危险节点的情况下走到到这个环,不然在模拟AC自动机匹配的时候无法到达这个这个环,也就失去了意义,楼上Dalao这里可能表述不尽准确)。

找环就属于图论了,DFS一遍,只不过必须从根节点出发(上面提到)。开两个布尔数组,一个记录历史是否访问过,一个记录是否在搜索的栈中。如果搜索过程中发现将要访问的下一个节点之间已经入栈了,就找到解了。不走危险节点,不走历史访问过而已经不在栈中的节点。还注意一下,如果某节点fail指向的是危险节点,那么该节点也是危险节点,AC自动机的性质,这里不再赘述。

多说几句,数据太小(因为年代久远?),根本不像AC自动机的题目。。。。。。提交记录都是0ms,若想冲榜要压空间,开short吧。我还是承认yyb_test比FlashHu强多啦!

下面是数组代码,可结合注释与上面的分析。

#include<cstdio>
#include<cstdlib>
const int N=33333;
short c[N][2],f[N],q[N];//没错short
bool e[N],vis[N],inst[N];
char s[N];
void dfs(short u)
{
if(inst[u])puts("TAK"),exit(0);//找到啦,直接拜拜
if(vis[u]||e[u])return;//走不通
inst[u]=vis[u]=1;
dfs(c[u][0]);
dfs(c[u][1]);
inst[u]=0;//两个标记意义不同,这个记得搜完清0
}
int main()
{
fread(s,1,N,stdin);
short n,i,u,v,cnt=0,h=0,t=0;
char*p=s;
n=*p&15;
while(*++p>' ')n*=10,n+=*p&15;
//建自动机
while(n--)
{
while(*++p<=' ');
for(u=0;*p>' ';++p)
{
if(!c[u][i=*p&1])c[u][i]=++cnt;
u=c[u][i];
}
e[u]=1;//标记危险节点(这时还没把所有的危险节点都找出来)
}
//处理fail以及危险节点
if(c[0][0])q[++t]=c[0][0];
if(c[0][1])q[++t]=c[0][1];
while(h<t)
{
u=q[++h];
for(i=0;i<=1;++i)
if((v=c[u][i]))f[q[++t]=v]=c[f[u]][i],e[v]|=e[f[v]];
//这时候才都找出来了
else c[u][i]=c[f[u]][i];//直接改空儿子,方便失配处理
}
dfs(0);
puts("NIE");//这时全搜遍了还没找到
return 0;
}

洛谷P2444 [POI2000]病毒(AC自动机,DFS求环)的更多相关文章

  1. 洛谷 P2444 [POI2000]病毒 解题报告

    P2444 [POI2000]病毒 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已 ...

  2. P2444 [POI2000]病毒 AC自动机

    P2444 [POI2000]病毒 #include <bits/stdc++.h> using namespace std; ; struct Aho_Corasock_Automato ...

  3. 【洛谷】P2444 [POI2000]病毒——AC自动机

    题目链接 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段, ...

  4. [洛谷P2444] [POI2000]病毒

    洛谷题目链接:[POI2000]病毒 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会 ...

  5. 【BZOJ2938】[Poi2000]病毒 AC自动机+DFS

    [BZOJ2938][Poi2000]病毒 Description 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码 ...

  6. 洛谷2414(构建ac自动机fail树dfs序后遍历Trie树维护bit及询问答案)

    要点 这是一道蔡队题,看我标题行事 任意询问y串上有多少个x串,暴力找每个节点是不是结尾肯定是炸的,考虑本质:如果某节点是x的结尾,根据ac自动机的性质,x一定是此(子)串后缀.又有每个Trie节点的 ...

  7. BZOJ2938[Poi2000]病毒——AC自动机

    题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段,试问,是否 ...

  8. [POI2000]病毒 --- AC自动机

    [POI2000]病毒 题目描述: 二进制病毒审查委员会最近发现了如下的规律: 某些确定的二进制串是病毒的代码. 如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的. 现在委员会已经找 ...

  9. BZOJ2938:[POI2000]病毒(AC自动机)

    Description 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码 ...

随机推荐

  1. python基础dict,集合,文件

    字典是一种key:value的数据类型dict1{ 'stud1':'孙礼昭', 'stud2':'slz', 'stud3':'sunlizhao',}dict是无序的,key是唯一的  天生去重增 ...

  2. 【JavaWeb】JDBC连接MySQL数据库

    正文之前 在之前写的JavaWeb项目中使用了JDBC,在此来回顾一下,并做个demo看看,先来看看JDBC的概念 Java数据库连接,(Java Database Connectivity,简称JD ...

  3. LearnPython_week2

    1.    列表.元组 2.    字典 3.    集合 4.    字符串的各种姿势 5.    OPEN文件操作 1.   列表.元组 列表 names = ['wong','caiyun',' ...

  4. php get_called_class()函数与get_class()函数的区别

    get_class (): 获取当前调用方法的类名: get_called_class():获取静态绑定后的类名: class Foo{ public function test(){ var_dum ...

  5. mac 查看某个文件夹下所有隐藏文件(夹)的大小

    du -d 1 -h 对应Linux的命令是: du -ah --max-depth=1

  6. JVM性能监控与故障处理命令汇总(jps、jstat、jinfo、jmap、jhat、jstack)

    给一个系统定位问题的时候,知识.经验是关键基础,数据是依据,工具才是运用知识处理数据的手段 使用适当的虚拟机监控和分析的工具可以加快我们分析数据.定位解决问题的速度,本文主要介绍了几款服 务器上常用的 ...

  7. Entity Framework——记录执行的命令信息

    有两种方法可以记录执行的SQl语句: 使用DbContext.Database.Log属性 实现IDbCommandInterceptor接口 一 使用DbContext.Database.Log属性 ...

  8. 机器学习之支持向量机(四):支持向量机的Python语言实现

    注:关于支持向量机系列文章是借鉴大神的神作,加以自己的理解写成的:若对原作者有损请告知,我会及时处理.转载请标明来源. 序: 我在支持向量机系列中主要讲支持向量机的公式推导,第一部分讲到推出拉格朗日对 ...

  9. 使用phpstorm提交svn代码版本管理系统遇到的问题解决办法

    1.当自己提交代码的时候显示out of date的时候,表示我们本地的代码过时啦,需要更新一下再提交. 即:更新一下再提交即可. 2.当自己的代码和服务器上的冲突的时候,我们右键点击冲突的文件,选择 ...

  10. JAVA多线程与并发学习总结

    1.      计算机系统 使用高速缓存来作为内存与处理器之间的缓冲,将运算需要用到的数据复制到缓存中,让计算能快速进行:当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存读写了. 缓 ...