【模板】AC自动机(简单版)
我:“woc。。。AC自动机?”
我:“可以自动AC???”
然鹅。。。
大佬:“傻。。。”
我:“(⊙_⊙)?”
大佬:“缺。。。”
我:“。。。。。。”
(大佬。。。卒 | 逃。。。)
emm。。。好吧。。。让我们来看看AC自动机是啥。。。
写在前面:如果没有学过 KMP 和 Trie树,请先理解这两个算法。。。
这个东西因为是一个歪果仁发明,然后两个单词的首字母为AC,所以就被叫做AC自动机了。。。
这个东西简单来说 AC自动机 == Trie + KMP
我们需要维护的东西也很简单,类似于Trie树上的KMP中的next数组。。。(作用类似,代表意义不同)
在AC自动机中有一个 fail 叫做失配指针。。。就是用它来进行跳转进行匹配
这样我们就可以发现。。。
Trie树维护多个字符串的功能 + KMP判子串的功能 == AC自动机匹配多个字符串
emm。。。讲解原理比较麻烦,直接看代码和注释比较好懂,当然建议根据大体的原理先瞎搞一波再看
呆码:
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std; struct asd{
int fail; // 失配指针
int vis[]; // 子节点的位置
int end; // 标记有几个单词以这个节点结尾
} AC[];
int rt,cnt,l,n;
char ch[]; inline void build(char *ch)
{
int l=strlen(ch+);
int now=rt,v;
for(int i=;i<=l;i++)
{
v=ch[i]-'a';
if(!AC[now].vis[v]) AC[now].vis[v]=++cnt;
now=AC[now].vis[v];
}
AC[now].end+=;
} inline void get_fail()
{
queue <int> Q;
for(int i=;i<=;i++) // 第一层肯定没有之前的点与他匹配
if(AC[rt].vis[i])
Q.push(AC[rt].vis[i]); // 因为默认是 0 所以没有写指向根节点
while(!Q.empty())
{
int u=Q.front(); Q.pop();
for(int i=;i<=;i++) // 枚举所有子节点
{
if(AC[u].vis[i]) // 存在这个子节点
{
AC[AC[u].vis[i]].fail=AC[AC[u].fail].vis[i];
// 子节点的fail指针指向当前节点的
// fail指针所指向的节点的相同子节点
Q.push(AC[u].vis[i]);
}
else //不存在这个子节点
AC[u].vis[i]=AC[AC[u].fail].vis[i];
// 当前节点的这个子节点指向当
// 前节点fail指针的这个子节点
}
}
} inline int query(char *ch)
{
int l=strlen(ch+);
int now=rt,ans=,u;
for(int i=;i<=l;i++)
{
u=ch[i]-'a';
now=AC[now].vis[u];
for(int j=now; j && AC[j].end!=-; j=AC[j].fail)
{
ans+=AC[j].end;
AC[j].end=-;
}
}
return ans;
} int main()
{
cin>>n;
for(int i=;i<=n;i++)
{
scanf("%s",ch+);
build(ch);
}
get_fail();
scanf("%s",ch+);
printf("%d\n",query(ch));
return ;
}
带注释
【模板】AC自动机(简单版)的更多相关文章
- [模板][P3808]AC自动机(简单版)
Description: 求n个模式串中有几个在文本串中出现 Solution: 模板,详见代码: #include<bits/stdc++.h> using namespace std; ...
- luoguP3808[模板]AC自动机(简单版)
传送门 ac自动机模板题,裸的多串匹配 代码: #include<cstdio> #include<iostream> #include<algorithm> #i ...
- 洛谷.3808/3796.[模板]AC自动机
题目链接:简单版,增强版 简单版: #include <cstdio> #include <cstring> const int N=1e6+5,S=26; char s[N] ...
- POJ 1625 Censored!(AC自动机->指针版+DP+大数)题解
题目:给你n个字母,p个模式串,要你写一个长度为m的串,要求这个串不能包含模式串,问你这样的串最多能写几个 思路:dp+AC自动机应该能看出来,万万没想到这题还要加大数...orz 状态转移方程dp[ ...
- luoguP3796[模板]AC自动机(加强版)
传送门 ac自动机模板,可能我写的ac自动机是有点问题的,所以跑的有些慢 暴力跳fail统计 代码: #include<cstdio> #include<iostream> # ...
- Ring HDU - 2296 AC自动机+简单DP和恶心的方案输出
题意: 就是现在给出m个串,每个串都有一个权值,现在你要找到一个长度不超过n的字符串, 其中之前的m个串每出现一次就算一次那个字符串的权值, 求能找到的最大权值的字符串,如果存在多个解,输出最短的字典 ...
- 算法模板——AC自动机
实现功能——输入N,M,提供一个共计N个单词的词典,然后在最后输入的M个字符串中进行多串匹配(关于AC自动机算法,此处不再赘述,详见:Aho-Corasick 多模式匹配算法.AC自动机详解.考虑到有 ...
- 模板 AC自动机
题目描述 有$N$ 个由小写字母组成的模式串以及一个文本串$T$ .每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串$T$ 中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据 ...
- 算法竞赛模板 AC自动机
AC自动机基本操作 (1) 在AC自动机中,我们首先将每一个模式串插入到Trie树中去,建立一棵Trie树,然后构建fail指针. (2) fail指针,是穿插在Trie树中各个结点之间的指针,顾名思 ...
- 小明系列故事――女友的考验 HDU - 4511 AC自动机+简单DP
题意:自己看题目,中文体面. 题解: 把所有不能走的路径放入AC自动机中. 然后DP[i][j]表示走到 i 这个点,且位于AC自动机 j 这个节点最短距离 然后直接DP即可.注意一点会爆int #i ...
随机推荐
- 看到篇博文,用python pandas改写了下
看到篇博文,https://blog.csdn.net/young2415/article/details/82795688 需求是需要统计部门礼品数量,自己简单绘制了个表格,如下: 大意是,每个部门 ...
- win10系统同时安装python2和python3
1.官网下载python2和python3版本 2.安装python3,勾上Add Python3.5 to PATH,自定义选择安装目录,安装,验证:WIN+R--->cmd,输入python ...
- 『Python』setup.py简介
setup.py应用场合 网上见到其他人这样介绍: 假如我在本机开发一个程序,需要用到python的redis.mysql模块以及自己编写的redis_run.py模块.我怎么实现在服务器上去发布该系 ...
- ACM-ICPC 2018 南京赛区网络预赛Skr
题意:求本质不同的回文子串的和 题解:先构造pam,然后根据pam的原理(ch表示在该节点表示的回文串两侧加上该字符)对于每个节点维护一个表示该节点字符串的值,加起来即可 //#pragma GCC ...
- aboutme and my goal
active, diligent ,work hard now,I am a sophomore,I must workhard ,ecspacially my major ,so , pass CE ...
- Thymeleaf使用bootstrap及其bootstrap相关插件(一)
Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷. 在完成信息录入界面 ...
- introsort(内省排序)
本文转载于:https://blog.csdn.net/sky453589103/article/details/51116264 快速排序是一种很快的算法,它平均的时间复杂度WieO(nlgn), ...
- Oracle11g温习-第十三章:索引
2013年4月27日 星期六 10:46 1.索引(Index)的功能:对记录进行排序,加快表的查询速度 2.索引的分类 1)B-tree 索引(默认) a.在一个大表上 b.建立在重复值比较少的 ...
- 一道PHP题引出的“短路求值”
今天群里有个人问了一个问题,代码如下: $a = 3; $b = 2; if ($a = 2 || $b = 5) { ++$a; } echo $a; 说代码段的执行的结果为1,问大家$a的 ...
- ES6 开发常用新特性以及简述ES7
一.关于变量 ES6新增:块级作用域变量 1.let定义块级作用域变量 没有变量的提升,必须先声明后使用 let声明的变量,不能与前面的let,var,conset声明的变量重名 { { consol ...