今天花了半天肝下AC自动机,总算啃下一块硬骨头,熬夜把博客赶出来。。

正如许多博客所说,AC自动机看似很难很妙,而事实上不难,但的确很妙。笼统地说,AC自动机=Trie+KMP,但是仅仅知道这个并没有什么用,该写不出来的还是写不出来,必须理解每一步的精确含义。KMP算法的精髓是“用自己匹配自己”,即:如果前i个字符失配时应该转移到第j个字符,那么前i+1个字符失配时应该比较i+1与j+1处的字符。AC自动机是一样的道理,只不过将图画在一颗Trie上,看起来不像KMP那样直观。用语言去描述构造失配边时的过程是这样的:设当前结点和字符分别为u和c,父亲结点的失配边指向v,如果v下有对应c的边,那么说明u的失配边应该指向ch[v][c](因为恰好匹配,公共前缀不变);否则将u视为v的子结点(也可以理解为给v建一个虚拟子结点对应c,然后递归求解虚拟结点的失配边),去找v的失配边指向的结点,直到找到或者v为根结点。

下面用一个例子解释一下这个过程:

现在为Trie加入失配边(这张图有点乱,建议一个点一个点地捋,找到规律就好办了)

朴素的AC自动机就长这样了(红色的边代表失配边)。每次匹配字符串时,如果失配,就沿着失配边一直走直到匹配;如果匹配就对当前结点追溯其失配边,找到所有在自动机中的当前匹配到的字符串的后缀(因为它们本不会被计入答案)。

对于上面的例子,匹配时访问的结点顺序为:1,7,8,23,24,18,19,15,22,3。由于与KMP算法一样,至多回溯O(m)次,因此保证了复杂度是线性的O(n+m)。

事实上,AC自动机有一些优化的方法:  

1.既然每次匹配时我要沿失配边找sum不为0的结点(即存在自动机中的完整字符串,而不是字符串的前缀),那么我为什么不直接开一个数组去存这些失配边指向的第一个sum不为0的结点呢?这样明显剩下一些时间。尽管理论上成立,但是我不建议使用这个优化,因为它不仅使AC自动机的代码变得冗长,还不一定有成效(毕竟只是常数优化)。

2.按我上面的介绍,失配与匹配是两种不同的状态,有不同的应对方法,但实际上两者差距并不大,仔细想想我上文的解释:将u视为v的子结点,进行递归求解,也就是说,失配其实就是匹配到了失配边所连接的结点的子结点。两者密不可分,甚至可以通过一些技巧将两者用同样的方法进行处理——只要将建立失配边的过程中,u的c子结点不存在时,ch[u][c]赋值为ch[fail[u]][c]即可。然后匹配时就不需要考虑失配的情况了,统一按匹配的情况进行转移,写起来方便多了。

例题:HDU 2222 Keywords Search

这道题就是一道AC自动机模板题,除了注意初始化外没有坑,适合上手。

其他题目以后更新。(其实是因为我才学,也只做了一道题)

代码

UPD(2017.12.24):

例题二:UVaLive 4670 Dominating Patterns(鉴于UVaLive的网站很多人上不去,包括我,我就传vjudge的链接了)P.S.这道题在洛谷上有原题,数据可能加强了一点,这里放出传送门

这题也算是模板题,注意一下模板串可以重复,推荐用map存重复的字符串的编号。还有就是数据范围,哪个是n,哪个是模板串长度要分清(我一开始就在这里RE一次)。

代码

AC自动机讲解的更多相关文章

  1. AC自动机讲解+[HDU2222]:Keywords Search(AC自动机)

    首先,有这样一道题: 给你一个单词W和一个文章T,问W在T中出现了几次(原题见POJ3461). OK,so easy~ HASH or KMP 轻松解决. 那么还有一道例题: 给定n个长度不超过50 ...

  2. AC自动机讲解超详细

    begin:2019/5/2 感谢大家支持! AC自动机详细讲解 AC自动机真是个好东西!之前学KMP被Next指针搞晕了,所以咕了许久都不敢开AC自动机,近期学完之后,发现AC自动机并不是很难,特别 ...

  3. [BZOJ4327]:[JZOI2012]玄武密码(AC自动机)

    题目传送门 题目描述: 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此.  ...

  4. [BZOJ3940]:[Usaco2015 Feb]Censoring(AC自动机)

    题目传送门 题目描述: FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过105的字符串S.他有一个包含n个单词的列表,列表里的n个单词记为t1…tN.他希望从S中删除这些单词.FJ每次在S中 ...

  5. [BZOJ1030]:[JSOI2007]文本生成器(AC自动机+DP)

    题目传送门 题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群, 他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...

  6. [BZOJ1195]:[HNOI2006]最短母串(AC自动机+BFS)

    题目传送门 题目描述 给定n个字符串(S1,S2,…,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,…,Sn)都是T的子串. 输入格式 第一行是一个正整数n,表示给定的字符串的个数 ...

  7. 算法总结篇---AC自动机

    目录 写在前面 算法流程 引例: 概述: Trie树的构建(第一步) 失配指针(第二步) 构建失配指针 字典树和字典图 多模式匹配 例题 写在前面 鸣谢: OiWiki 「笔记」AC 自动机---Lu ...

  8. AC自动机基础知识讲解

    AC自动机 转载自:小白 还可参考:飘过的小牛 1.KMP算法: a. 传统字符串的匹配和KMP: 对于字符串S = ”abcabcabdabba”,T = ”abcabd”,如果用T去匹配S下划线部 ...

  9. 一个在开源中国博客上讲解的AC自动机

    原文出处:http://my.oschina.net/amince/blog/196426 原 荐 AC(Aho—Corasiek) 多模式匹配算法 摘要 如何在一篇文章中,搜索多个关键字,如何快速查 ...

随机推荐

  1. SpringBoot里mybatis查询结果为null的列不返回问题的解决方案

    对于mybatis里查询结果为null的列不返回的问题解决方案 在配置文件application.properties里增加 Mybatis.configuration.call-setters-on ...

  2. Java之路上,让我们Stand Up Again

    在开始之前,先发表一下个人想法吧. 在读书的时候每天忙的不可开交,也就没有了所谓的自由,突然参加工作,传统的朝八晚五,标准的八小时工作制,每天都是两点一线,工作中涉及商业机密,公司的东西也不能带回家, ...

  3. AI 系列 总目录

    AI 系列 答应了园区大牛 张善友 要写AI 的系列博客,所以开始了AI 系列之旅. 一.四大平台系列(百度AI.阿里ET.腾讯.讯飞) 1.百度篇 (1) 百度OCR文字识别-身份证识别 (2) 基 ...

  4. CSS文字不换行,溢出省略

    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;

  5. 百度云BCC配置Apache VirtualHost 实现相同域名不同端口访问不同应用

    问题描述:前戏:本人在百度云上购买了BCC虚拟服务,并购买域名,部署应用,可以正常访问(这里一切都很正常^_^). 事情正在起变化:随着开发的不断推进,工程在本地测试成功后,部署到服务器,会发现有些页 ...

  6. n年前,我没钱但年轻,我怕n年后我老时,还是一无所成——2017我的收获和反思

    记得当年我刚从学校里出来时,应该和现在的95后差不多,当时还是很惶恐的,怕找不到工作,怕无法挣到足够的钱买房子支撑家庭,(当然还有其它的担心点),却唯独没意识到自己拥有着最宝贵的财富:年轻. 年轻意味 ...

  7. 78、excel的读写操作

    本篇主要是用python来自动生成excel数据文件也就是简单的excel读写操作.python读写excel文件主要是第三方模块库xlrd.xlwt. 本篇导航: 写excel 读excel 一.写 ...

  8. Nodejs进阶:crypto模块中你需要掌握的安全基础

    本文摘录自<Nodejs学习笔记>,更多章节及更新,请访问 github主页地址. 一. 文章概述 互联网时代,网络上的数据量每天都在以惊人的速度增长.同时,各类网络安全问题层出不穷.在信 ...

  9. asp.net core 2.0+sqlsugar搭建个人网站系列(0)

    一些废话 马上就要过年了,回顾这一年最大的收获就是技术有了很大的提升,其他的方面没有什么改变,现在还是单身小屌丝一枚. 这一年来学习的主要重点就是asp.net core,中间也使用 core+EF做 ...

  10. python3.5 + PyQt5 +Eric6 实现的一个计算器

    目前可以实现简单的计算.计算前请重置,设计的时候默认数字是0,学了半天就做出来个这么个结果,bug不少. python3.5 + PyQt5 +Eric6 在windows7 32位系统可以完美运行 ...