洛谷P2444 病毒【AC自动机】
题目描述
二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。
示例:
例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。
任务:
请写一个程序:
1.在文本文件WIR.IN中读入病毒代码;
2.判断是否存在一个无限长的安全代码;
3.将结果输出到文件WIR.OUT中。
输入输出格式
输入格式:
在文本文件WIR.IN的第一行包括一个整数n(n\le 2000)(n≤2000),表示病毒代码段的数目。以下的n行每一行都包括一个非空的01字符串——就是一个病毒代码段。所有病毒代码段的总长度不超过30000。
输出格式:
在文本文件WIR.OUT的第一行输出一个单词:
TAK——假如存在这样的代码;
NIE——如果不存在。
输入输出样例
题意:
给n个模式串,问能不能找到一个无限长的文本串,使得模式串没有出现在文本串里。
思路:
看到题目没想法......看了题解
我们会发现正常的AC自动机都是在文本串中去匹配模式串,现在不要模式串出现,那么也就是说希望Trie中被标记为模式串结尾的节点不要出现。我们将这个称为危险标记。而想要无限长的文本串,其实也就是在匹配过程中能否找到这样一个环,使得环上的节点都是安全的。
首先我们还是先建立fail数组,需要注意的是,如果一个节点的fail指针指向的节点是危险的,那么他本身也是危险的。
因为一个节点x的fail指针指向的节点y表示的是以y作为结尾的前缀与以x为结尾的前缀的后缀匹配的最长部分,也就是说根节点到y一定是在根节点到x中出现过的。
然后dfs,用一个数组vis标记路径,一个数组f标记是否访问过。vis在dfs结束后要恢复,是用来判断当前路径是否形成环的。
#include <iostream>
#include <set>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long LL;
#define inf 0x7f7f7f7f int n;
const int maxn = ; struct Tree{
int fail;//失配指针
int vis[];//子节点位置
int ed;//标记有几个单词以这个节点结尾
}AC[maxn];
string s;
int tot = ; void build(string s)
{
int len = s.length();
int now = ;//字典树当前指针
for(int i = ; i < len; i++){
if(AC[now].vis[s[i] - ''] == ){
AC[now].vis[s[i] - ''] = ++tot;
}
now = AC[now].vis[s[i] - ''];
}
AC[now].ed = ;
} void get_fail()
{
queue<int> que;
for(int i = ; i < ; i++){
if(AC[].vis[i] != ){
AC[AC[].vis[i]].fail = ;
que.push(AC[].vis[i]);
}
}
while(!que.empty()){
int u = que.front();
que.pop();
for(int i = ; i < ; i++){
if(AC[u].vis[i] != ){
AC[AC[u].vis[i]].fail = AC[AC[u].fail].vis[i];
if(AC[AC[u].fail].ed){
AC[u].ed = ;
}
que.push(AC[u].vis[i]);
}
else{
AC[u].vis[i] = AC[AC[u].fail].vis[i];
}
}
}
} bool vis[maxn], f[maxn];
void dfs(int rt)
{
vis[rt] = true;
for(int i = ; i < ; i++){
if(vis[AC[rt].vis[i]]){
printf("TAK\n");
exit();
}
else if(!AC[AC[rt].vis[i]].ed && !f[AC[rt].vis[i]]){
f[AC[rt].vis[i]] = true;
dfs(AC[rt].vis[i]);
}
}
vis[rt] = false;
} int main()
{
scanf("%d", &n);
for(int i = ; i < n; i++){
cin>>s;
build(s);
}
AC[].fail = ;
get_fail();
dfs();
printf("NIE\n");
//cout<<s[maxid]<<endl;
//cout<<AC_query(s)<<endl;
return ;
}
洛谷P2444 病毒【AC自动机】的更多相关文章
- 洛谷 - P2444 - 病毒 - AC自动机
https://www.luogu.org/problemnew/show/P2444 有点恶心,不太明白fail的意义. #include<bits/stdc++.h> using na ...
- 洛谷P2444 病毒 [POI2000] AC自动机
正解:AC自动机 解题报告: 传送门! 首先看到这种题目二话不说先把trie树和fail指针建立起来 然后就想鸭,如果我们想让模式串和文本串尽量不能匹配,就要想办法让它跳fail指针,而不是继续往下走 ...
- 洛谷 - P3966 - 单词 - AC自动机
https://www.luogu.org/problemnew/show/P3966 因为文本串就是字典本身,所以这个和平时的AC自动机不太一样.平时的query要沿着fail树把子树的出现次数依次 ...
- 洛谷P3808 & P3796 AC自动机模板
题目:P3808:https://www.luogu.org/problemnew/show/P3808 P3796:https://www.luogu.org/problemnew/show/P37 ...
- 洛谷.3121.审查(AC自动机 链表)
题目链接 //删掉一个单词需要前移一段位置,用链表维护就好了 复杂度O(sum(len)) #include <cstdio> #include <cstring> #defi ...
- 洛谷P2444 [POI2000]病毒(AC自动机,DFS求环)
洛谷题目传送门 AC自动机入门--yyb巨佬的博客 AC自动机入手经典好题(虽然年代久远) 有了fail指针,trie树就不是原来的树型结构了,我们可以把它叫做trie图,由父节点向子节点连的边和fa ...
- 【洛谷 P2444】 [POI2000]病毒(AC自动机)
题目链接 这么多字符串,肯定是自动机啦. 先建出AC自动机,然后怎么表示一个安全代码没有病毒代码呢? 就是存在一条路径不经过有病毒代码段结尾的节点呗. 所以呢?有环啊!dfs一下救星了. #inclu ...
- 【洛谷】P2444 [POI2000]病毒——AC自动机
题目链接 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段, ...
- [洛谷P2444] [POI2000]病毒
洛谷题目链接:[POI2000]病毒 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会 ...
随机推荐
- oracle 死锁和锁等待的区别
所谓的锁等待:就是一个事务a对一个数据表进行ddl或是dml操作时,系统就会对该表加上表级的排它锁,此时其他的事务对该表进行操作的时候会等待a提交或是回滚后,才可以继续b的操作 所谓的死锁:当两个或多 ...
- Oracle 11gR2 11.2.0.1 ( 11.2.0.1的BUG?):ohasd不能正常启动:ioctl操作:npohasd的问题:【chmod a+wr /var/tmp/.oracle/npohasd】
问题1:执行安装,编译成功后,执行asmca时,失败,无法成功创建后台相关服务 问题2:os系统重启后,ohasd无法正常启动,css服务失败 原因:11.2.0.1的BUG:/var/tmp/.or ...
- 详解MathType中如何插入特殊符号
在论文写作中,经常会用到一些特殊符号,MathType公式编辑器支持插入特殊符号,并且数量繁多,可以满足用户的需求.本教程将详解MathType如何插入特殊符号. MathType中插入特殊符号的操作 ...
- Navicat for Mysql 如何备份数据库
Navicat for Mysql 如何备份数据库 打开界面如下 打开自己的的数据库 点击需要备份的数据库名 未完!!! 文章来自:http://jingyan.baidu.com/article/f ...
- crc16算法,包括单片机和c#版本
c语言的#include <stdio.h> static short const wCRC16Table[256] = { 0x0000, 0xC0C1, 0xC181 ...
- BZOJ 1089 SCOI2003 严格n元树 动态规划+高精度
题目大意:定义一棵深度为d的严格n元树为根的深度为0,最深的节点深度为d,且每一个非叶节点都有恰好n个子节点的树 给定n和d,求深度为d的严格n元树一共同拥有多少种 此题的递推部分并不难 首先我们设深 ...
- swift - UIScrollView 的使用
本节详细介绍scrollview的用法 ———————————————————————————————————— UIScrollView 是一个能够滚动的视图控件,可以用来展示大量的内容,并且可以通 ...
- Android中文API
Android中文API http://www.android-doc.com/index.html
- Xdebug安装与使用
为什么需要Debugger? 很多PHP程序员调试使用echo.print_r().var_dump().printf()等,其实对 于有较丰富开发经验的程序员来说这些也已经足够了,他们往往可以在程序 ...
- 安装memcacheq
1.下载memcacheq包 下载地址:http://code.google.com/p/memcacheq/downloads/list 解压包:# tar -zxvf memcache ...