「LuoguP3808」 【模板】AC自动机(简单版)
题目背景
通过套取数据而直接“打表”过题者,是作弊行为,发现即棕名。
这是一道简单的AC自动机模板题。
用于检测正确性以及算法常数。
为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交。
管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意
题目描述
给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。
输入输出格式
输入格式:
第一行一个n,表示模式串个数;
下面n行每行一个模式串;
下面一行一个文本串。
输出格式:
一个数表示答案
输入输出样例
说明
subtask1[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6,n=1;
subtask2[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6;
题解
在通常就没什么人认真听的集训里,qwerta刚撸完一把Win7原装的扫雷,舒适的抬起头,正好对上了老师讲fail树的眼神。
所以是懂一丢丢手推方法的。
建议大家先构造点小数据手推,像是什么在$her,him,he,his,she$上匹配$shehisher$之类的。
网上教程也蛮多,就不画图了。(懒
其实是自己也推不蛮清楚
然后是教材QAQ yyb大佬的博客
总之,AC自动机就是在trie树上bfs一下然后乱搞,可以理解为trie上的KMP叭。
自己都不怎么会,就不讲这个东西了QAQ
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define R register
const int MAXL=1e6+;
char s[MAXL];
struct emm{
int fail;
int nxt[];
int tag;
}AC[MAXL];//Tree结构体
queue<int>q;//get_fail的时候用的queue
int main()
{
//freopen("a.in","r",stdin);
ios::sync_with_stdio(false);
cin.tie(false);cout.tie(false);
int n;
cin>>n;
int tot=;
//trie
while(n--)
{
cin>>s;
int len=strlen(s);
int now=;//now表示当前的节点编号
for(R int i=;i<len;++i)
{
if(!AC[now].nxt[s[i]-'a'])//如果当前节点没有这个儿子
AC[now].nxt[s[i]-'a']=++tot;//就造个儿子
now=AC[now].nxt[s[i]-'a'];//now跳到这个儿子上
}
AC[now].tag++;//now最后在的地方是这个模式串的结束点,标记一下
}
//get_fail
{
//首先把跟0号节点相连的点处理一下
for(R int i=;i<;++i)
{
if(AC[].nxt[i])//如果这个儿子存在
{
AC[AC[].nxt[i]].fail=;//把fail指向0号节点(其实默认就是0啊QAQ
q.push(AC[].nxt[i]);//把这个儿子push进去
}
}
while(!q.empty())
{
int x=q.front();q.pop();//取点
for(R int i=;i<;++i)
{
if(AC[x].nxt[i])//如果这个儿子存在
{
AC[AC[x].nxt[i]].fail=AC[AC[x].fail].nxt[i];//敲重点!!!
//这个儿子的fail,等于这个节点fail的儿子 会手推就能懂叭QAQ
q.push(AC[x].nxt[i]);//push进去
}
else
AC[x].nxt[i]=AC[AC[x].fail].nxt[i];//这里直接把nxt指向了fail的对应儿子
}
}
}
//run
cin>>s;
long long ans=;
int len=strlen(s);
int now=;//now表示当前节点编号
for(R int i=;i<len;++i)
{
now=AC[now].nxt[s[i]-'a'];//往下走一层(因为之前直接把空的nxt往fail指了,所以不需要通常的while跳fail
//大概就是Trie图和Trie树的区别了叭
for(R int t=now;t&&AC[t].tag!=-;t=AC[t].fail)//从这个点开始暴力跳fail,找匹配
{
ans+=AC[t].tag;
AC[t].tag=-;//这是个剪枝
}
}
cout<<ans;
return ;//撒花
}
然后吐槽一下咕咕的数据,之前有一大段把$now$和$i$混用了,结果还过了一个点(???
「LuoguP3808」 【模板】AC自动机(简单版)的更多相关文章
- LG2444/BZOJ2938 「POI2000」病毒  AC自动机
		问题描述 LG2444 BZOJ2938 I \(\mathrm{AC}\)自动机 \(\mathrm{AC}\)自动机是一种多模式串匹配算法,本萌新今天刚学了它qwq 约定在构造\(\mathrm{ ... 
- [模板][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$ 中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据 ... 
随机推荐
- DICOM:DICOM万能编辑工具之Sante DICOM Editor
			版权声明:本文为zssure原创文章,转载请注明出处,未经允许不得转载. 目录(?)[-] 背景 DICOM Service的配置 Sante DICOM Editor自启动的服务 PACS查询下 ... 
- 如何防范SQL注入式攻击
			一.什么是SQL注入式攻击? 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令.在某些表单中,用户输入的内容直接用来构造(或者 ... 
- 怎么设置MySQL就能让别人访问本机的数据库了?
			for all ips use below GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%' WITH GRANT OPTION; for particular ... 
- JavaWeb页面添加隐藏版权信息
			JavaWeb页面添加隐藏版权信息. 首先,我推荐一个值得玩味的版权站点,有兴趣的朋友能够去看上一看.Nazo Level 1,这个demo中我能发掘到有5个步骤,你看你能发现几层? 接下来.我来介绍 ... 
- Node.js知识点学习
			Node.js知识点学习 一.基本概念 Node.js,或者 Node,是一个可以让 JavaScript 运行在服务器端的平台.可以说,Node.js开创了javascript模块化开发的先河,早期 ... 
- final  和static
			一.final 1.final变量: 当你在类中定义变量时,在其前面加上final关键字,那便是说,这个变量一旦被初始化便不可改变,这里不可改变的意思对基本类型来说是其值不可变,而对于对象变量来说其引 ... 
- __del__删除方法
			class dog: def __del__(self): print("删除机制被调用了...") dog1 = dog() del dog1 #在这里是先删除掉了,所以就去上面 ... 
- angularJS  contenteditable  指令双向绑定
			项目遇到需求有点奇葩:双击div使其可编辑,失去焦点后进行数据绑定 通过自定义指令完成 好了上代码: .directive('contentEditable', function() { return ... 
- MySQL 创始人:写代码比打游戏爽,程序员应多泡开源社区
			王练 发布于2017年09月04日 收藏 43 开源中国全球专享福利,云栖大会购票大返现!>>> 根据StackOverflow的最新调查,MySQL仍然是全世界最流行的数 ... 
- tensor搭建--windows 10 64bit下安装Tensorflow+Keras+VS2015+CUDA8.0 GPU加速
			windows 10 64bit下安装Tensorflow+Keras+VS2015+CUDA8.0 GPU加速 原文见于:http://www.jianshu.com/p/c245d46d43f0 ... 
