今天花了半天肝下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. 八.利用springAMQP实现异步消息队列的日志管理

    经过前段时间的学习和铺垫,已经对spring amqp有了大概的了解.俗话说学以致用,今天就利用springAMQP来完成一个日志管理模块.大概的需求是这样的:系统中有很多地方需要记录操作日志,比如登 ...

  2. [转载]ArchLinux 添加 archlinuxcn 源 密钥错误

    http://www.jianshu.com/p/8ed688b0a096 杜龙少 正在检查密钥环里的密钥 [######################] 100% 正在下载所需的密钥...... ...

  3. 55、js对象

    在python中我们学习了面向对象,javascript也是一门面向对象语言,在JavaScript中除了null和undefined以外其他的数据类型都被定义成了对象. JavaScript的对象简 ...

  4. 小白的Python之路 day4 装饰器前奏

    装饰器前奏: 一.定义: 1.装饰器本质是函数,语法都是用def去定义的 (函数的目的:他需要完成特定的功能) 2.装饰器的功能:就是装饰其他函数(就是为其他函数添加附加功能) 二.原则: 1. 不能 ...

  5. Ubuntu字符界面输入密码始终提示错误 login incorrect 解决办法

    方法1. 先输入用户名按enter,然后ctrl+alt+f7 切换回图形界面,然后再切换到字符界面输密码 方法2.先输入用户名按enter,然后关闭小键盘上的numlock按键再打开,再输入密码 f ...

  6. 【model模型传入view的数据类型错误】传入字典的模型项的类型为“System.Data.Entity.Infrastructure.DbQuery`1[MapScience.PovertyAlleviation.Web.Models.Qu

    出现这个问题的原因是控制器中传给view的数据类型与View中设置的model类型不一致导致,比如控制器返回的IList类型的,而你在View里面model设置的是IEnumerable<> ...

  7. bzoj 3999: [TJOI2015]旅游

    Description 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会 ...

  8. nova创建虚拟机源码分析系列之八 compute创建虚机

    /conductor/api.py _build_instance()  /conductor/rpcapi.py  _build_instance() 1 构造一些数据类型2 修改一些api版本信息 ...

  9. QT中定时器的使用方法

    前言:因为QT中用死循环会开销很多内存容易崩溃,这时候使用定时器可以很好解决这个问题. 使用定时器需要用到头文件:include<QTimer> (1)定义定时器 QTimer *upda ...

  10. ajax调用数据案例,二级联动

    题目:请针对移动端web浏览器制作一个结账数据信息展示页面 要求: 1. 页面样式除不使用表格呈现外,可自由选择其他呈现方式 2. 需符合移动端操作习惯 3. 可根据服务区.门店查询结账信息 4. 可 ...