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

这道题目要求构造一个无限长的文本串,使得其中没有模式串出现,利用AC自动机原理,通过单向边和失配指针寻找不含危险标记的环。通过DFS寻找环并避免危险标记,优化失配指针构建。解题过程中需要注意路径标记和历史访问记录,以及避免误判环的情况。
摘要由CSDN通过智能技术生成

作为一道蹂躏了我一天的题…我也没啥好说的了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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值