P2444 [POI2000] 病毒

题目核心是多模式匹配,所以考虑用对所有模式串建立AC自动机。

我们把自动机上,存在一个模式串作为前缀的节点,称作“危险节点”。

如果无限长的安全代码存在的话,匹配过程中Trie图上一定有节点会经过多次,即存在环;而且经过的所有节点都不是“危险节点”,否则就包含病毒代码段了。

所以我们只需要看Trie图上是否存在不包含危险节点的环,就能得到答案了。

可以用一个dfs实现这一过程。用\(vis\)来表示节点访问状态,初始全为\(0\):

  • \(vis[u]=0\):\(u\)未被访问过。
  • \(vis[u]=1\):\(u\)正在处理中。
  • \(vis[u]=-1\):从\(u\)出发找不到环。

如果只用\(0,1\)而不用\(-1\)来剪枝优化,时间复杂度可能由线性退化到指数级,将无法通过hack数据。

bool dfs(int u){
if(vis[u]==1) return 1;
if(vis[u]==-1) return 0;
vis[u]=1;
for(int i=0;i<C;i++)//C=2
if(!en[tr[u][i]]&&dfs(tr[u][i]))
return 1;//en[x]=1表示x是危险节点
vis[u]=-1;
return 0;
}

最后就是如何判断某个节点是不是危险节点,这个可以在get_fail()中处理出来。如果节点\(u\)是模式串的结尾,或者\(fail[u]\)是危险节点,那么\(u\)就是危险节点。

时间复杂度\(O(\sum|s|\times |\Sigma|)\)。

点击查看代码
#include<bits/stdc++.h>
#define N 30010//节点数(模式串总长)
#define C 2//字符集大小
using namespace std;
int n,tr[N][C],fail[N],cnt;
int q[N],head,tail,vis[N];
bool en[N];
string s;
void ins(string s){
int p=0;
for(char i:s){
int c=i-'0';
if(!tr[p][c]) tr[p][c]=++cnt;
p=tr[p][c];
}
en[p]=1;
}
void get_fail(){
head=0,tail=-1;
for(int i=0;i<C;i++) if(tr[0][i]) q[++tail]=tr[0][i];
while(head<=tail){
int u=q[head++];
for(int i=0;i<C;i++){
int& v=tr[u][i];
if(v) fail[v]=tr[fail[u]][i],q[++tail]=v,
en[v]|=en[fail[v]];
else v=tr[fail[u]][i];
}
}
}
bool dfs(int u){
if(vis[u]==1) return 1;
if(vis[u]==-1) return 0;
vis[u]=1;
for(int i=0;i<C;i++)
if(!en[tr[u][i]]&&dfs(tr[u][i]))
return 1;
vis[u]=-1;
return 0;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>s;
ins(s);
}
get_fail();
if(dfs(0)) cout<<"TAK\n";
else cout<<"NIE\n";
return 0;
}

[题解]P2444 [POI2000] 病毒的更多相关文章

  1. P2444 [POI2000]病毒

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

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

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

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

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

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

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

  5. 洛谷P2444 [POI2000]病毒(AC自动机,DFS求环)

    洛谷题目传送门 AC自动机入门--yyb巨佬的博客 AC自动机入手经典好题(虽然年代久远) 有了fail指针,trie树就不是原来的树型结构了,我们可以把它叫做trie图,由父节点向子节点连的边和fa ...

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

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

  7. BZOJ2938 & 洛谷2444:[POI2000]病毒——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2938 https://www.luogu.org/problemnew/show/P2444 二进制 ...

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

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

  9. BZOJ2938 [Poi2000]病毒 和 BZOJ5261 Rhyme

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

  10. 2021.11.10 [POI2000]病毒(AC自动机)

    2021.11.10 [POI2000]病毒(AC自动机) https://www.luogu.com.cn/problem/P2444 题意: 二进制病毒审查委员会最近发现了如下的规律:某些确定的二 ...

随机推荐

  1. java如何启动时定义并初始化一个全局变量(内存中)

    前言 java如何启动时定义并初始化一个全局变量(内存中),项目启动时,通过读取配置文件来构建一个实体类对象,然后在之后可以直接使用,而不是每次使用都要进行构建 前置准备 实体类结构 package ...

  2. [SWPUCTF 2021 新生赛]finalrce

    <?php highlight_file(__FILE__); if(isset($_GET['url'])) { $url=$_GET['url']; if(preg_match('/bash ...

  3. python的 range() 函数

    python range() 函数可创建一个整数列表,一般用在 for 循环中. range(start, stop[step]) range(10) # 从 0 开始到 10 [0, 1, 2, 3 ...

  4. MyBatisPlus逆向工程

    MyBatisPlus逆向工程 一.创建Springboot工程 二.引入pom依赖 <?xml version="1.0" encoding="UTF-8&quo ...

  5. 保姆级教程!玩转 ChunJun 详细指南

    ChunJun是一款稳定.易用.高效.批流一体的数据集成框架,⽀持海量数据的同步与计算.ChunJun 既可以采集静态的数据,比如 MySQL,HDFS 等,也可以采集实时变化的数据,比如 binlo ...

  6. 超赞!本地程序调用云知识库实现RAG功能

    在 Spring AI Alibaba 程序中,我们可以直接使用本地程序调用百炼平台的云知识库,实现知识库文档解析.分块.向量化存储等一条龙服务. 这样,开发者就不用本地部署搭建向量数据库.不用进行复 ...

  7. Http 中所有的 data 中base64 类型

    https://blog.csdn.net/webxiaoma/article/details/70053444 一.我们在看代码时经常在img或css背景图片中看到: src="data: ...

  8. Spring AI 对话记忆大揭秘:服务器重启,聊天记录不再丢失!

    还在为 Spring AI 应用重启后对话上下文丢失而烦恼吗?本文将带你深入 Spring AI 的对话记忆机制,并手把手教你实现一个基于文件的持久化方案,让你的 AI 应用拥有 "过目不忘 ...

  9. 树莓派4安装centos

    下载镜像这是用的华为的镜像源仓库中下载的,注意不要下载桌面版的centos,安装不上,直接彩虹屏.下载第三个就行http://mirrors.huaweicloud.com/centos-altarc ...

  10. C语言中如何不用strcat函数来连接2个数组

    C语言中如何不用strcat函数来连接2个数组? 今天就遇到这个问题,所以就尝试了一下,虽然这个问题被好多大佬看作就不是问题,但我还是对这方面做个简单的介绍. 下面是我的代码和运行情况. 其实简单的引 ...