题目描述


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

示例:
例如如果{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. phpstrom安装bootstrap3插件

    1.步骤 File > > Settings > >Plugins > > 搜索bootstrap 3 然后点击 Browse repositories 就会有一个 ...

  2. 理解Bitcode:一种中间代码

    原文网址: http://www.cocoachina.com/ios/20150818/13078.html 今天试着用Xcode 7 beta 3在真机(iOS 8.3)上运行一下我们的工程,结果 ...

  3. UIWebView 使用

    UIWebView是iOS sdk中一个最常用的控件.是内置的浏览器控件,我们可以用它来浏览网页.打开文档等等.这篇文章我将使用这个控件,做一个简易的浏览器.如下图: 我们创建一个Window-bas ...

  4. ubuntu 14.04 源码编译postgresql

    环境 ubuntu 14.04 桌面版 postgresql 源码下载链接,本教程是使用postgresql 9.3.4 进行编译的 http://www.postgresql.org/ftp/sou ...

  5. typescript学习笔记(三)---接口

    关于第二章的学习笔记是变量声明. 接口:TypeScript的核心原则之一是对值所具有的结构进行类型检查. 它有时被称做“鸭式辨型法”或“结构性子类型化”. 在TypeScript里,接口的作用就是为 ...

  6. G - B-number

    #include<stdio.h> #include<string.h> using namespace std; typedef long long ll; ]; ][][] ...

  7. IP服务-3-DHCP

    DHCP代表了动态IP地址分配的下一阶段.DHCP建立在BOOTP协议格式的基础上,专注于动态分配多种信息,以及为未来的扩展提供灵活的消息结构,并且无需预先定义每个客户端的MAC地址.DHCP提供的功 ...

  8. 复习线程——状态和几个Thread方法

    一.线程的状态 (参考文章:https://blog.csdn.net/a58220655/article/details/76695142) 状态介绍 新建(new):处于该状态的时间很短暂.已被分 ...

  9. 安卓 使用LruCache 加载图片 遇到的问题

    本来 使用listview的时候 加载大图片的时候 会遇到内存溢出而导致崩溃. 但是使用LruCache的时候 原本以为可以 解决这个问题.  但是发现还是出现了内存溢出的情况.   困扰很久 另外, ...

  10. 解决部分浏览器不能显示itext生成的PDF文件文本域内容问题

    利用Itext可以实现pdf的高效动态生成,但在实践过程中遇到了一个问题: 即itext利用map中的值设置到pdf模板上建立的文本域中时:能成功生成,但是在部分浏览器上(360,QQ,等浏览器)无法 ...