[算法模版]AC自动机
[算法模版]AC自动机
基础内容
板子不再赘述,OI-WIKI有详细讲解。
\(query\)函数则是遍历文本串的所有位置,在文本串的每个位置都沿着\(fail\)跳到根,将沿途所有元素答案++。意义在于累计所有以当前字符为结尾的所有模式串的答案。看代码就能很容易的理解。
另外\(e[i]\)记录的是第\(t\)个模式串结尾是哪个节点(所有节点均有唯一的编号)。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#define maxn (int)(2e6+10000)
int ch[(int)(2e5+1000)][30],fail[maxn],cnt,e[maxn],nex[maxn],n,myque[maxn],ans[maxn],head[maxn],idx;
using namespace std;
char s[(int)(2e6+1)];
char data[maxn];
struct gg {
int u,v,next;
}side[maxn*2];
void ins(int u,int v) {
side[++idx]=(gg){u,v,head[u]};head[u]=idx;
}
void init() {
memset(ch,0,sizeof(ch));
memset(fail,0,sizeof(fail));
memset(e,0,sizeof(e));
memset(nex,0,sizeof(nex));
memset(ans,0,sizeof(ans));
cnt=0;
}
void insert(int t) {
int now=0,len=strlen(s);
for(int i=0;i<len;i++) {
int num=s[i]-'a';
if(!ch[now][num])ch[now][num]=++cnt;
now=ch[now][num];
}
e[t]=now;
}
void build(){
int l=0,r=0;
for(int i=0;i<=26;i++)if(ch[0][i])myque[++r]=ch[0][i];
while(l<r) {
int now=myque[++l];ins(now,fail[now]),ins(fail[now],now);//确定now儿子的fail指针
for(int i=0;i<=26;i++) {
if(ch[now][i]) {
myque[++r]=ch[now][i];
fail[ch[now][i]]=ch[fail[now]][i];
// ins(ch[now][i],ch[fail[now]][i]);ins(ch[fail[now]][i],ch[now][i]);
}
else ch[now][i]=ch[fail[now]][i];
}
}
}
void query() {
int now=0;
for(int i=0;data[i];i++) {
now=ch[now][data[i]-'a'];
//for(int j=now;j;j=fail[j])ans[j]++;
ans[now]++;
}
}
void dfs(int x,int f) {
for(int i=head[x];i;i=side[i].next) {
int v=side[i].v;if(v==f)continue;
dfs(v,x);
}
ans[f]+=ans[x];
}
int main() {
init();
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%s", s);
insert(i);
}
build();
scanf("%s", data);
query();//for(int i=cnt;i>=0;i--);
dfs(0,0);
//for(int i=cnt;i>=1;i--)ans[fail[i]]+=ans[i];
for(int i=1;i<=n;i++)printf("%d\n",ans[e[i]]);
return 0;
}
last优化(引自sclbgw7)
博主懒,就不造轮子了。原文链接见参考文献。
上述方法将建图+匹配的复杂度成功优化为了 $
[算法模版]AC自动机的更多相关文章
- 算法模板——AC自动机
实现功能——输入N,M,提供一个共计N个单词的词典,然后在最后输入的M个字符串中进行多串匹配(关于AC自动机算法,此处不再赘述,详见:Aho-Corasick 多模式匹配算法.AC自动机详解.考虑到有 ...
- 【字符串算法】AC自动机
国庆后面两天划水,甚至想接着发出咕咕咕的叫声.咳咳咳,这些都不重要!最近学习了一下AC自动机,发现其实远没有想象中的那么难. AC自动机的来历 我知道,很多人在第一次看到这个东西的时侯是非常兴奋的.( ...
- hdu2222 Keywords Search(AC自动机初步)
题目大意: 给出多个模式串和一个主串,求多少个模式串在主串中出现过. 传送门 这是一道AC自动机的模板题. 在学习AC自动机之前,首先要学习WA自动机.TLE自动机和MLE自动机(雾 AC自动机是一种 ...
- 浅谈AC自动机
写在前面:从10月23日开始写这篇博文,离NOIP2018只有十多天了.坚持不停课的倔强蒟蒻(我)尽量每天挤时间多搞一搞信竞(然而还要准备期中考试).NOIP争取考一个好成绩吧. 一.简介 AC自动机 ...
- AC自动机学习笔记-1(怎么造一台AC自动机?)
月更博主又来送温暖啦QwQ 今天我们学习的算法是AC自动机.AC自动机是解决字符串多模匹配问题的利器,而且代码也十分好打=w= 在这一篇博客里,我将讲解AC自动机是什么,以及怎么构建一个最朴素的AC自 ...
- 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序
[题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...
- 【BZOJ】2553: [BeiJing2011]禁忌 AC自动机+期望+矩阵快速幂
[题意]给定n个禁忌字符串和字符集大小alphabet,保证所有字符在集合内.一个字符串的禁忌伤害定义为分割能匹配到最多的禁忌字符串数量(一个可以匹配多次),求由字符集构成的长度为Len的字符串的期望 ...
- 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂
[题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...
- AC 自动机——多模式串匹配
网站上的敏感词过滤是怎么实现的呢? 实际上,这些功能最基本的原理就是字符串匹配算法,也就是通过维护一个敏感词的字典,当用户输入一段文字内容后,通过字符串匹配算法来检查用户输入的内容是否包含敏感词. B ...
随机推荐
- Python的设计哲学--zen of Python
Python的设计哲学--zen of Python Beautiful is better than ugly. 优美胜于丑陋 Explicit is better than ...
- Scala 系列(五)—— 集合类型综述
一.集合简介 Scala中拥有多种集合类型,主要分为可变的和不可变的集合两大类: 可变集合: 可以被修改.即可以更改,添加,删除集合中的元素: 不可变集合类:不能被修改.对集合执行更改,添加或删除操作 ...
- 在eclipse中,用maven创建一个web项目工程
1.在eclipse中用maven创建项目,右键new>>Maven Project 2.点击next继续 3.点击next继续,选择maven-archetype-webapp, 4.点 ...
- Go语言http包简易入门
说道go语言web编程,必不可少的会使用到net/http包.go语言将web开发需要使用到的很多内容都放在了标准库中——net/http. 如何写一个简单的web程序很容易.如下: package ...
- 排序算法Java代码实现(五)—— 快速排序
本篇内容: 快速排序 快速排序 算法思想: 通过一趟排序将要排序的数据分割成独立的两部分, 其中一部分的所有数据都比另外一部分的所有数据都要小, 然后再按此方法对这两部分数据分别进行快速排序, 整个排 ...
- os.path.join()函数的用法
转:https://blog.csdn.net/hduxiejun/article/details/80289476 os.path.join()函数:连接两个或更多的路径名组件 1.如果各组件名 ...
- mysql的my.cnf
配置参数详解 [client] #客户端设置,即客户端默认的连接参数port = 3307 #默认连接端口socket = /data/mysqldata/3307/mysql.sock #用于本 ...
- 使用Fiddler监听java HttpURLConnection请求
使用Fiddler监听java HttpURLConnection请求
- Linux使用pt-archiver工具自动备份MySQL
操作系统: CentOS 6.9 脚本语言: shell https://github.com/iscongyang/Practical/blob/master/shell-scripts/pt-ar ...
- wordpress中文目录出现“有点尴尬诶!该页无法显示"
原因不详,可能是.htaccess.网上说删除后再更新固定链接会再生成,但是我没有.我又把原来的.htaccess上传后更改固定链接为“数字型”,测试后可以正常浏览. 然后又再更改为原来的“日期和名称 ...