洛谷P2444 病毒(AC自动机变形)

洛谷 P3808 【模板】AC 自动机(简单版) AC 自动机模板 阅读详情

作为一道蹂躏了我一天的题…我也没啥好说的了QAQ…
思路概述
我们知道,AC自动机是一种多模字符串匹配算法。构造 Trie 树 后,在模式串末尾一位的结点作上标记。平常的 AC自动机 是尽量能多接触到这些标记,使总值最大。本题倒是有点奇葩,要构造一个可行的无限长文本串,使没有任何子串为给出模式串中的一个。也就是说,我们需要让平常 AC自动机 的查询操作,尽量避免标记,能用失配指针跳转就跳转。

因为要有无限长的可行串,根据 AC自动机 的原理,我们可以将结点连接到儿子的边当作一条单向边,同时失配指针也当作一条单向边,如果存在一个环,且环上没有任何危险标记(即病毒代码段末尾一位的结点专门作的编号),此时 AC自动机 能一直在环上匹配,并且永远也不会得到为模式串的一个子串,就像程序中的死循环一样。这个找环我们可以通过 dfs 来实现。

注意事项
1 . 我们需要建立两个布尔数组,其中一个布尔数组记录每个节点在当前 dfs 走的路径上有没有被选中,另一个布尔数组记录每个节点历史上有没有被访问过。如果当前路径形成回路,就找到环了,应该还是比较好实现的。
2 . 避免危险标记,也就是说如果下一个结点拥有危险标记,就不走那个结点。
3 . 在构造失配指针时,一个很明显的优化是:如果一个结点拥有了失配指针,它指向的结点如果有危险标记,自己必然也危险,因为它到根结点形成的串是自己到根节点的后缀。
4.为什么要两个bool标记?因为如图1,如果不能保证当前dfs时在sta中的节点是链式结构的话,就会可能出现误判为环的可能。
5.为什么要在造指针的时候做优化,除了时间上的考虑似乎还有别的因素…如图吧。否则的话,如果只访问子节点,那永远成不了环。访问fail节点的话,又可能自环。
这里写图片描述

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
struct node{
    node*next1[2];
    node*fail;
    bool tag,vis,insta;//tag标记是否为单词结尾,vis表示此节点是否被访问过,insta表示此节点是否正在被访问的链上
    node(){
        memset(next1,0,sizeof(next1));fail=NULL;tag=vis=insta=false;
    }
}*root=new node();
int cnt=0;
void insert(string str)
{
    node*p=root;
    for(int i=0;i<str.size();i++){
        int x=str[i]-'0';
        if(!p->next1[x]){
            node*t=new node();p->next1[x]=t;
        }
        p=p->next1[x];
    }
    p->tag=true;
}
void build_fail_pointer(void)
{
    node*p,*temp;
    queue<node*>que;que.push(root);
    while(!que.empty()){
        temp=que.front();que.pop();
        for(int i=0;i<2;i++){
            if(temp->next1[i]){
                if(temp==root){
                    temp->next1[i]->fail=root;
                }
                else{
                    p=temp->fail;
                    while(p){
                        if(p->next1[i]){
                            temp->next1[i]->fail=p->next1[i];
                            if(p->next1[i]->tag)temp->next1[i]->tag=true;//如果指向的失配节点是结尾,考虑到失配节点到root的过程中
                            //是一个单词,那么拥有相同后缀的原节点自然也是结尾.优化要放在这里否则可能出现遗漏
                            break;
                        }
                        p=p->fail;
                    }
                    if(!p)temp->next1[i]->fail=root;
                }
                que.push(temp->next1[i]);
            }
            else temp->next1[i]=temp->fail->next1[i];//优化,如果没有下一个节点,那么该节点就指向失配指针的对应节点
            //不过这个优化放在有ac_automation函数的题目中似乎会re,具体原因暂时不明
        }
    }
}
void dfs(node*p)
{
    p->vis=p->insta=true;
//    if(p->fail&&p->fail->tag){
//        p->insta=false;return;
//    }
    if(p->next1[0]){
        if(p->next1[0]->insta){//这就解决了所有在sta中的节点都被访问过而不能再访问的问题,确保不会重复访问而且可以正确判断成环
            cout<<"TAK"<<endl;exit(0);
        }
        if(!p->next1[0]->tag&&!p->next1[0]->vis)
            dfs(p->next1[0]);
    }
    if(p->next1[1]){
        if(p->next1[1]->insta){
            cout<<"TAK"<<endl;exit(0);
        }
        if(!p->next1[1]->tag&&!p->next1[1]->vis)
            dfs(p->next1[1]);
    }
    p->insta=false;
}
int main()
{
    int n,i,j;string str;
    cin>>n;
    for(i=1;i<=n;i++){
        cin>>str;insert(str);
    }
    build_fail_pointer();
    dfs(root);
    cout<<"NIE"<<endl;

    return 0;
}
HDU 自动 AC 机(Python) 一款 HDU OJ 的自动刷题工具,搜索来源可选用 百度搜索 / 必应搜索,支持并行以及串行查找,祝早日刷上航电首页哦~ 使用 Python 编写,执行之前你需要在同目录下创建文件 aclog.txt ,然后粘贴进你目前已经 AC 的题目,然后在代码执行过程中便不会去再查找这些题了。 立即下载

相关推荐

全栈开发指南:从前端到后端的全面掌握

全栈开发人员(Full Stack Developer)是指能够处理前端和后端开发工作的开发人员。他们需要掌握各种技术和工具,能够独立完成从需求分析、设计、开发到部署的整个流程。这篇博客将详细介绍全栈开发涉及的各个方面,为您提供从入门到进阶的指导。

Where there is a will, there is a way ! 3451

【洛谷 P3808】【AC自动机】 AC自动机(简单版)

【洛谷 P3808】【AC自动机】 AC自动机(简单版) 题目 解题思路 建一个trie树然后在上面跑kmp 代码 #include<iostream> #include<cstring> #include<cstdio> using namespace std; string s; int x,l,c,w,n,ans,tot,q[1000010],tr[500010][30],ed[500010],nxt[1000010]; void add() { x=

Y的博客 282

全局子程序 参数调用

为什么要子程序: 为了实现程序结构化,我们尽量使用不同功能的功能块来实现一些特定的功能, 子程序接口: 使用过程的注意事项,尤其是数组使用时的注意事项 从一个主程序中可以将参数传递到局部或全局子程序和函数中。 怎样传递参数有 2 种方式: 作为 IN 参数 变量值在主程序中保持不变。 这种传递方式也称为“ 值传递 (Call by Value)”。 作为 OUT 参数 子程序读取并更改该值,然后将新值写回到主程序中。 这种传递方式也称为“Call by Reference”。 举例说明 1 DEF MY

Eric_Yang1024的博客 1095

【Luogu】 P2444 [POI2000]病毒

无

djx2021的博客 187

virtualbox虚拟机里面最顶部没有控制、设置和帮助等选项

无意中操作,导致virtualbox虚拟机里面最顶部没有控制,设置和帮助选项  virtualbox虚拟机窗口显示如下如: 如何设置,窗口显示如下图所示呢: virtualbox虚拟机窗口模式显示设置,切换可以通过如下图所示操作进行切换: PS:一定要是右边的Ctrl+C

WEL测试 8780

自然语言处理之机器翻译:Transformer:Transformer在低资源语言翻译中的应用

Transformer模型是自然语言处理领域的一个重要突破,由Vaswani等人在2017年的论文《Attention is All You Need》中提出。它摒弃了传统的循环神经网络(RNN)和卷积神经网络(CNN)的序列依赖性,采用自注意力机制(Self-Attention)处理输入序列,极大地提高了训练效率和模型性能。

zhubeibei168的博客 1014

洛谷 P3808 【模板】AC自动机(简单版)

AC 自动机模板题 不做详细解释,但是强调几个代码中需要注意到的地方 AC 自动机第一步利用字典树将模式串放入树中 第二步利用 BFS 构建 fail 指针,构造 fail 指针时需要注意,构建节点 u(x代表节点 u 中的字母)的 fail 指针时,是在其父节点位置时构造的,当 x存在时,其 fail 指针指向其父节点 fail 指针中的 x节点;而当 x不存在时,只要将 u 指向其父节点 fail 指针中的 x节点,这样可以在后续查找当中从字典树的底部跳到树顶(不明白...

C_Dreamy的博客 871

SAP和Oracle EBS作为全球顶级的ERP系统,在中国市场深耕数十年,尤其是在大型国企、央企和跨国企业中,已经形成了强大的用户习惯和“舒适区”依赖

国产ERP替代国际系统的关键挑战在于打破用户对SAP/Oracle的操作习惯和心理依赖。需采取多维策略:战略上明确价值主张、分阶段实施;产品上优化用户体验、确保数据迁移;实施上加强情景化培训、流程再造。成功替代70%取决于变革管理,需将"被动替换"转为"主动升级",让用户在新系统中建立更优的舒适区。

金牌架构师 383

洛谷 P3796 【模板】AC自动机(加强版)

题目要求出现最多的模式串及次数,我们目前可以利用 AC 自动机找到一个东西,那就是模式串 这样不就好解决了吗?利用一个数组存取每一个模式串的出现次数,最后在统计一边就可以了 const int N=1e6+5; int n,m; int i,j,k; char s[N]; int f[N]; int t[N][26],tot=0; int vis[N]; char ch[155][75]; int ans[N]; int ...

C_Dreamy的博客 475

TensorRT的安装:一步一步教会你如何安装TensorRT

TensorRT(Tensor Runtime)是由NVIDIA开发的一个用于深度学习推理(inference)优化的库,它可以在NVIDIA的GPU上加速神经网络模型的推理过程,从而提高模型的性能和效率。安装完成后,需要将CUDA的安装路径添加到系统环境变量中,以便系统能够找到CUDA的库文件。根据你安装的CUDA版本,将CUDNN的库文件复制到CUDA的安装目录中。要使用TensorRT,首先需要安装NVIDIA的CUDA和cuDNN库,并根据NVIDIA官方文档安装TensorRT。

Science prince的博客 2373

yolov8 PTQ和QAT量化实战(源码详解)

量化():是指将高精度浮点数(FP32)转换为低精度(8bit或4bit)整数的过程,它是模型部署中的一种非常重要的优化方法,可以在较少的精度损失下,大幅提供神经网络的效率和性能。目前主流的神经网络量化方式有PTQ和QATPTQ是训练后量化(),无需数据集和训练,直接量化模型权重QAT是量化感知训练(),量化后需要在数据集上继续微调训练。QAT过程中,我们首先需要选择哪些层需要进行finetune训练,并利用FP32对应层的输出作为监督进行训练。

@bangbang的博客 5326

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

P2444 [POI2000]病毒 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。 示例: 例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11...

weixin_30339457的博客 188

基于 YOLOv26 的遥感图像目标检测系统:从原理到模型

本文介绍了基于YOLOv26的遥感图像目标检测系统。YOLOv26凭借端到端设计、轻量化架构和小目标优化能力,有效解决了遥感图像中多尺度目标、复杂背景、小目标检测等挑战。系统采用CSPDarknet骨干网络和FPN+PAN特征融合模块,通过MuSGD优化器和改进损失函数提升训练效果。文章详细阐述了数据预处理、模型训练流程和优化技巧,包括Tile推理和混合精度训练。系统支持多种部署方式,在CPU上推理速度提升43%,能实现高精度、实时性的遥感目标检测,适用于城市规划、农业监测等场景。

一键难忘的博客 568

【洛谷】P3808 【模板】AC 自动机(简单版)

https://www.luogu.com.cn/problem/P3808题目背景: 这是一道简单的AC自动机模板题,用于检测正确性以及算法常数。题目描述: 给定nnn个模式串sis_isi​和一个文本串ttt,求有多少个不同的模式串在文本串里出现过。两个模式串不同当且仅当他们编号不同。输入格式: 第一行是一个整数,表示模式串的个数 nnn。 第 222 到第 (n+1)(n + 1)(n+1) 行,每行一个字符串,第 (i+1)(i + 1)(i+1) 行的字符串表示编号为 iii 的模式串 sis_i

数学、算法爱好者的博客 622

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【模板】AC自动机(加强版)

【模板】AC自动机(加强版) 题目描述 有NNN个由小写字母组成的模式串以及一个文本串TTT。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串TTT中出现的次数最多。 输入输出格式 输入格式: 输入含多组数据。 每组数据的第一行为一个正整数NNN,表示共有NNN个模式串,1≤N≤1501 \leq N \leq 1501≤N≤15...

loooooog的博客 226

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

洛谷 P2444 [POI2000]病毒

题目:病毒 思路: 首先把所有病毒代码建成trie。 然后建出fail指针,顺便完成AC自动机的优化。 然后分析样例可以获得这样一棵trie图—— 3 01 11 00000 其中黑边是trie的正常边,绿边是在处理AC自动机时连上的优化边,红边是fail指针。 节点内部的数是节点权值,旁边的是节点编号。 可以知道,一个无限的文本串,在AC自动机匹配的过程中一定会“死循环”,即存在环状的...

iwi 320

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【AC自动机】洛谷P3808 【模板】AC自动机(简单版)

题目链接:https://www.luogu.org/problem/P3808 AC自动机是看http://blog.c0per.org/2018-10/ac/和https://www.luogu.org/blog/juruohyfhaha/ac-zi-dong-ji看懂的,理解怎么操作不难,但是最主要要理解的是为什么这样子操作。 首先AC自动机是在字典树的基础上加了一些类似kmp的思想...

Uletay 370

自动AC机

仅供学习请勿在任何时候使用 首发于洛谷,我就是作者! 主程序 #include<bits/stdc++.h> #define MAXX (9999) using namespace std;string a="edit";char b[1000],c[1000];//edit为题目名称 void hhh(){ gets(b); a+=b[0]; a+=".out"; for(...

weixin_43762849的博客 4356

AC自动机 洛谷P3796

题目链接:https://www.luogu.org/problem/P3796 题意:给多个模式串和一个文本串,要求出模式串匹配最多的次数是多少,并输出这些次数的模式串。 分析:求匹配次数很明显,把AC_qurey函数稍微改一下就好,但要输出这些模式串我就迷了,当时认为Trie只能上到下,到了一个结点无法回到其上的结点,就不会了,事实上还是很浅显,另外用一个数组记录位置就好了啊。。...

weixin_30304375的博客 177

[POI2000]病毒,洛谷P2444,AC自动机

正题        题面        首先我们可以把这些病毒的AC自动机建出来。        发现,如果有答案,那么这个答案在这个AC自动机上不管怎么跳都不会跳到一个病毒的结尾。        那么我们就模拟跳的过程,如果成环了,输出TAK即可。 #include&lt;cstdio&gt; #include&lt;cstdlib&gt; #include&lt;cstring&g...

Deep_Kevin的娱乐空间 476

洛谷P2444 [POI2000]病毒

Description 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。 示例: 例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。 任务: 请写一个程序: l 读入病毒代码; l

tylon2006的博客 364

洛谷2444 [POI2000]病毒(AC自动机)(DFS)

题目 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。 示例: 例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么...

A_Bright_CH的博客 409

【洛谷】3808 【模板】AC自动机(简单版)

题目传送门 终于看懂啦!终于学会了AC自动机啦!(Flag立起)写篇博客梳理一下自己的思路吧。 在文章的开头,必须先放上一些大佬的博客来压压场面:我选的当然是ZZK大佬,神犇传送门 然而AC自动机的原理其实是比较好理解的,就是把Trie树和KMP的思想结合起来。这么说起来KMP就是单个字符串的AC自动机啊。(雾) 给出许多模式串,把这些字符串都加入到Trie树中,在每个字符串结尾的叶子节点

Chester King 755

AC自动机模板(【洛谷3808】)

题面题目背景这是一道简单的AC自动机模版题。用于检测正确性以及算法常数。为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交。 题目描述给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。输入格式:第一行一个n,表示模式串个数;下面n行每行一个模式串;下面一行一个文本串。输出格式:一个数表示答案输入输出样例输入样例#1:2 a aa aa输出样例#1:2说明subtask

小蒟蒻yyb的博客 3605

AC自动机模板(luoguP3808 【模板】AC自动机(简单版))

题目背景 这是一道简单的AC自动机模板题。 用于检测正确性以及算法常数。 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交。 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。 输入输出格式 输入格式: 第一行一个n,表示模式串个数; 下面n行每行一个模式串...

aoping9329的博客 207
上一篇: 洛谷P3808 AC自动机复杂版
下一篇: POJ2385
HumveeA6
博客等级 码龄17年 12粉丝 175原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值