[算法模版]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 ...
随机推荐
- HBase统计表行数(RowCount)的四种方法
背景:对于其他数据存储系统来说,统计表的行数是再基本不过的操作了,一般实现都非常简单:但对于HBase这种key-value存储结构的列式数据库,统计 RowCount 的方法却有好几种不同的花样,并 ...
- Mac下Homebrew将程序文件存在什么位置
一般情况是这么操作的: 1.通过brew install安装应用最先是放在/usr/local/Cellar/目录下. 2.有些应用会自动创建软链接放在/usr/bin或者/usr/sbin,同时也会 ...
- python2.7 与python3.X区别
1,print("中文") python2.7,会报错 原因:py2.7用ascll码 解决:2.7头部加入并保存的文件用utf-8编码 # -*- coding: utf-8 ...
- webuploader-异步切片上传(暂不支持断点续传)及 下载方法!C#/.NET
十年河东,十年河西,莫欺少年穷 学无止境,精益求精 进入正题: 关于webuploader,参考网址:https://fex.baidu.com/webuploader/: 本篇博客范例下载地址:ht ...
- MySQL语言分类——DDL
DDL的全称Data Definition Language,即数据定义语言 DDL的语法有:create.alter.drop.rename.truncate.对此做一个详细的解释: create ...
- Jenkins 任务定时
在项目配置中选择 Build Triggers 下勾选 Build periodically,可以对项目进行定时构建设置.构建设置详细可通过右边的问号符号进行查看. 定时构建字段遵循 cron 的语法 ...
- 记录Mac OS下编译Thrift库
方法一:brew管理工具安装Homebrew是Mac开发包管理工具,类似于Linux的apt-get之类的,实它相当于开发软件界的 Appstore.借助该管理工具,可以自动化地安装软件包,它会自动安 ...
- Qt 字符串截取 获取指定字符位置
获取字符在字符串中的位置 QString str = "AT+LOC+LOCATION: 115.850441,33.004833"; QString s = "LOC& ...
- MSSQL记录表字段数据变化的相关SQl
在软件实施过程中,也许会有这样的问题: 表中数据出现非预期的结果,此时不确定是程序问题,哪个程序,存储过程,触发器.. 或还是人为修改的结果,此时可以用触发器对特定的表字段做跟踪监视,记录每次新增,修 ...
- 深入理解Java封装、继承、多态
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10830957.html 一:封装 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法 ...