题目描述


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

示例:
例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。
任务:
请写一个程序:
l 读入病毒代码;
l 判断是否存在一个无限长的安全代码;
l 将结果输出

输入

第一行包括一个整数n,表示病毒代码段的数目。以下的n行每一行都包括一个非空的01字符串——就是一个病毒代码段。所有病毒代码段的总长度不超过30000。

输出

你应在在第一行输出一个单词:

l TAK——假如存在这样的代码。
l NIE——如果不存在。

样例输入

3
01
11
00000

样例输出

NIE
 
题解

多模式串匹配问题。
果断AC自动机(因为蒟蒻我也不会别的啊QAQ)
把每个病毒串插进trie树,get_fail这些基本操作大家想必都会啦
本题多了一个奇诡操作:fail环。
首先了解一下fail环
拉过来一张丑陋的图:
如上图为题目描述中为NIE的那个数据(好像少了个0……)。
显然上图中虚线表示的0并不存在。
所以dfs搜到他的时候,这个点指向root的右儿子的那个1的左儿子。
不过遗憾的是
这个0也不存在。
那么只好走这个1的fail指针,即root的右儿子,
然后我们发现,它还是会从root的右儿子去找到当前这个虚线框里的0
这次这个0指向了root的左儿子。
然后再顺下来我们发现又可以找到原来的1啦。
这就是fail环啦(至少我是这么理解的,大神别踩啊QAQ)
然后捏?
我们把插入时的endd设置成危险节点,
即不能访问的节点
然后一遍dfs就出来啦!
代码:
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#define rint register int
using namespace std;
char ch[30004];
int n;
int trie[30004][2];
int cnt=1,fail[30004];
bool endd[30004],vis[30004];
bool ans=false,failed[30004];
inline void insert(char *str)
{
int len=strlen(str),p=1;
for(rint i=0;i<len;++i)
{
int l=str[i]-'0';
if(!trie[p][l])
trie[p][l]=++cnt;
p=trie[p][l];
}
endd[p]=true;
}
inline void get_fail()
{
queue <int>q;
q.push(1);
fail[1]=0;
trie[0][0]=trie[0][1]=1;
while(!q.empty())
{
int l=q.front();q.pop();
for(rint i=0;i<2;++i)
{
if(trie[l][i])
{
fail[trie[l][i]]=trie[fail[l]][i];
if(endd[fail[trie[l][i]]])
endd[trie[l][i]]=true;//注意这两句话,没加毁人生QAQ
q.push(trie[l][i]);
}
else trie[l][i]=trie[fail[l]][i];
}
}
}
inline void dfs(int u)
{
vis[u]=1;
for(int i=0;i<=1;i++)
{
if(vis[trie[u][i]])
{
ans=true;
return ;
}
else if(!failed[trie[u][i]]&&!endd[trie[u][i]])
{
failed[trie[u][i]]=1;
dfs(trie[u][i]);
}
}
vis[u]=0;
return ;
}
int main()
{
// freopen("wir213.in","r",stdin);
scanf("%d",&n);
for(rint i=1;i<=n;++i)
{
scanf("%s",ch);
insert(ch);
}
get_fail();
// for(rint i=1;i<=cnt;++i)cout<<fail[i]<<endl;
dfs(1);
if(ans)cout<<"TAK"<<endl;
else cout<<"NIE"<<endl;
return 0;
}

完结撒花~

[BZOJ2938]病毒 (AC自动机+dfs)的更多相关文章

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

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

  2. 洛谷 P2444 [ POI 2000 ] 病毒 —— AC自动机+dfs

    题目:https://www.luogu.org/problemnew/show/P2444 AC自动机上 dfs,不走结尾点,如果走出环就是有无限长度的串: RE无数,原来是数组开成 2000 的了 ...

  3. BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

    一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...

  4. BZOJ2434[Noi2011]阿狸的打字机——AC自动机+dfs序+树状数组

    题目描述 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小 ...

  5. LG2444/BZOJ2938 「POI2000」病毒 AC自动机

    问题描述 LG2444 BZOJ2938 I \(\mathrm{AC}\)自动机 \(\mathrm{AC}\)自动机是一种多模式串匹配算法,本萌新今天刚学了它qwq 约定在构造\(\mathrm{ ...

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

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

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

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

  8. 【bzoj2938】[Poi2000]病毒 AC自动机

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

  9. [luoguP2444] [POI2000]病毒(AC自动机 + dfs)

    传送门 先把所有串建一个AC自动机, 如果要找一个不包含任意一个串的串, 说明这个串一直在AC自动机上匹配但匹配不到, 也就是说,匹配时除去val值为1的点,除去fail指针指向val值为1的点,是否 ...

随机推荐

  1. HDU4973 【几何。】

    题意: 给你一个以原点为圆心的两个圆,一个大圆,一个小圆,然后给你一个硬币和他的速度,问你经过大圆的时间: 思路: 直接杠.. 然后wa的怀疑人生,后面wa在了速度的方向,如果我说一个点在两个圆的左上 ...

  2. VC++11 编译中的一些问题的解决办法

    1.  vc++ 的编译器的错误往往定位在错误的那一处,但是那一处可能在库的底层,而我们知道库,一般都不会错. 这时候应该好好看看我们自己的头文件是否正确,有可能头文件中的一些错误引发了连锁反应. 2 ...

  3. python 之 函数 装饰器

    5.8 装饰器 1 开放封闭原则 软件一旦上线后,就应该遵循开放封闭原则,即对修改源代码是封闭的,对功能的扩展是开放的 也就是说我们必须找到一种解决方案: 能够在不修改一个功能源代码以及调用方式的前提 ...

  4. python自建模块显示说明与详情

    通常我们自建模块放在/usr/lib/python2.7/site-packages下面,这样可以python就可以进行调用. 但是,自建模块也要有详细的说明情况,例如查help,可以看出来模块的作用 ...

  5. jdbc学习day1

  6. H - String painter

    #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> ...

  7. $.each(obj,function(index,value)遍历的学习

    JQuery遍历对象 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  8. java小游戏——猜数字

    import java.util.ArrayList; import java.util.List; import java.util.Random; public class Num01 { sta ...

  9. Promise.then(a, b)与Promise.then(a).catch(b)问题详解

    原文: When is .then(success, fail) considered an antipattern for promises? 问题 我在bluebrid promise FAQ上面 ...

  10. JavaScript Allongé 序幕:值和表达式

    序幕:值和表达式   下面的内容非常基础,然而,就像大多数的故事一样,在最初的时候开始才是最好的开端. 想象一下,我们要去最喜欢的咖啡馆,他们会为你制作几乎任何你想要的饮料,从小而强烈的 Espres ...