[AC自动机][学习笔记]
用途
AC自动机适用于一类用多个子串在模板串中匹配的字符串问题。
也就是说先给出一个模板串,然后给出一些子串。要求有多少个子串在这个模板串中出现过。
KMP与trie树
其实AC自动机就是KMP与trie的结合版。或者说是在trie上进行的kmp算法。所以学会kmp和trie是学习AC自动机的基础。
对于上面那类问题。可以对于每个子串都用kmp算法在母串中匹配一次。但是复杂度就成了\(n^2\)
AC自动机
而对于这类问题,AC自动机的实现是先把所有的子串都挂到trie树上,然后在用母串去trie上匹配。
首先往trie上挂子串和普通的trie一样。就像这样
void add() {
int len = strlen(s + 1);
int now = 0;
for(int i = 1;i <= len;++i) {
if(!trie[now][s[i] - 'a']) trie[now][s[i] - 'a'] = ++tot;
now = trie[now][s[i] - 'a'];
}
val[now]++;
}
然后就要建立失配指针。也就是建立起一张trie图,与trie树的区别是这是一张图。(废话)。和kmp类似。如果当前节点下面有x这个字符,那么x的失配指针就指向当前节点失配指针的x孩子。否则,当前节点的儿子就是当前节点失配指针的x孩子。
代码就像这样
void build() {
for(int i = 0;i < 26;++i) if(trie[0][i]) fail[trie[0][i]] = 0,q.push(trie[0][i]);
while(!q.empty()) {
int u = q.front();q.pop();
for(int i = 0;i < 26;++i) {
if(trie[u][i]) fail[trie[u][i]] = trie[fail[u]][i],q.push(trie[u][i]);
else trie[u][i] = trie[fail[u]][i];
}
}
}
查询,那么如何查询呢。其实也很简单,像在trie树上查询一样在这个trie图上查询母串。每查询到一个节点,就不断的沿着他的fail指针跳,然后加上跳到的节点的标记(用来标记当前节点是多少个子串的结尾的标记)。并且标记为访问过了,防止以后重复访问。
代码就像这样
int query() {
int now = 0;
int ans = 0;
int len = strlen(S + 1);
for(int i = 1;i <= len;++i) {
now = trie[now][S[i] - 'a'];
for(int j = now;j && val[j] != -1;j = fail[j]) ans += val[j],val[j] = -1;
}
return ans;
}
其实AC自动机的用途非常广泛,并不是只能处理这一类问题。在各种题目中可以见到他的很多应用。
[AC自动机][学习笔记]的更多相关文章
- AC自动机学习笔记-2(Trie图&&last优化)
我是连月更都做不到的蒟蒻博主QwQ 考虑到我太菜了,考完noip就要退役了,所以我决定还是把博客的倒数第二篇博客给写了,也算是填了一个坑吧.(最后一篇?当然是悲怆のnoip退役记啦QAQ) 所以我们今 ...
- AC自动机板子题/AC自动机学习笔记!
想知道484每个萌新oier在最初知道AC自动机的时候都会理解为自动AC稽什么的,,,反正我记得我当初刚知道这个东西的时候,我以为是什么神仙东西,,,(好趴虽然确实是个对菜菜灵巧比较难理解的神仙知识点 ...
- AC自动机学习笔记-1(怎么造一台AC自动机?)
月更博主又来送温暖啦QwQ 今天我们学习的算法是AC自动机.AC自动机是解决字符串多模匹配问题的利器,而且代码也十分好打=w= 在这一篇博客里,我将讲解AC自动机是什么,以及怎么构建一个最朴素的AC自 ...
- AC 自动机学习笔记
虽然 NOIp 原地爆炸了,目前进入 AFO 状态,但感觉省选还是要冲一把,所以现在又来开始颓字符串辣 首先先复习一个很早很早就学过但忘记的算法--自动 AC AC自动机. AC 自动机能够在 \(\ ...
- AC自动机学习笔记
AC自动机 ----多个模板的字符串匹配 字典树Trie加上失配边构成 插入操作:ac.insert(p[i],i);构造失配函数:ac.getFail();计算文本串T中每个模板串的匹配数:ac.f ...
- 【AC自动机】【字符串】【字典树】AC自动机 学习笔记
blog:www.wjyyy.top AC自动机是一种毒瘤的方便的多模式串匹配算法.基于字典树,用到了类似KMP的思维. AC自动机与KMP不同的是,AC自动机可以同时匹配多个模式串, ...
- AC自动机学习
今天包括这一周开始学习AC自动机了,有点晚,但我感觉努努力还来得及.4月份还得认认真真攻图论,加油! 为2个月后的邀请赛及省赛.东北赛做准备. 推荐AC自动机学习地址:http://www.cppbl ...
- 后缀自动机&回文自动机学习笔记
在学了一天其实是边学边摆之后我终于大概$get$后缀自动机了,,,就很感动,于是时隔多年我终于决定再写篇学习笔记辽$QwQ$ $umm$和$FFT$学习笔记一样,这是一篇单纯的$gql$的知识总结博, ...
- AC自动机学习小结
AC自动机 简要说明 \(AC\) 自动机,全称 \(Aho-Corasick\ automaton\) ,是一种有限状态自动机,应用于多模式串匹配.在 \(OI\) 中通常搭配 \(dp\) 食用. ...
随机推荐
- Java多线程系列——原子类的实现(CAS算法)
1.什么是CAS? CAS:Compare and Swap,即比较再交换. jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronou ...
- Java集合和数组的区别
参考:Java集合和数组的区别 集合和容器都是Java中的容器. 区别 数组特点:大小固定,只能存储相同数据类型的数据 集合特点:大小可动态扩展,可以存储各种类型的数据 转换 数组转换为集合: A ...
- 解决spring多线程不共享事务的问题
在一个事务中使用多线程操作数据库时,若同时存在对数据库的读写操作,可能出现数据读取的不准确,因为多线程将不会共享同一个事务(也就是说子线程和主线程的事务不一样),为了解决这个问题,可以使用spring ...
- PHP namespace、require、use区别
假设 有文件a.php 代码 <?php class a{//类a public function afun()//函数afun { echo "aaaa"; } } ?&g ...
- Ubuntu Firefox HTML5
sudo apt-get install ubuntu-restricted-extras
- How to hosts
sudo cp /etc/hosts /etc/hosts.bak sudo cp ~/Desktop/hosts /etc/hosts sudo systemctl restart NetworkM ...
- How to enable flash on Chromium
sudo apt install chromium-browser pepperflashplugin-nonfree
- mysql分页查询按某类型置顶 按某类型置尾 再按优先级排序
近段时间接到一个新需求: 第一优先级:未满的标的顺位高于已满标的顺位.第二优先级:新手标的顺位高于其他标的的顺位. 第三优先级:标的剩余可投金额少的顺位高于标的剩余可投金额多的. 我是直接通过sql语 ...
- Newton方法
Newton方法主要解决无等式约束和等式约束的最优化方法. 1.函数进行二阶泰勒展开近似 Taylor近似函数求导等于0进而得到Newton步径.(搜索方向) 2.Newton减量(停止条件) 当1/ ...
- 行为驱动开发(BDD) - 深入了解
行为驱动开发(BDD) - 一个快速的描述和示例 BDD表示乙 ehavior ð里文ð才有发展.用于描述行为的语法是Gherkin. 这个想法是尽可能自然地描述一种语言应该发生什么. 如果你熟悉单元 ...