浙江集训Day9,没有出任何实质性成果,只好把昨天打完的板子记一下. 该博客基于luogu的三道模版题.只有一个大致的讲解,主要提供代码给自己参考. ----------------------------------------------------------------------- (7.14) 一.AC自动机 AC自动机,一个有着令人容易误会的名字的有限状态自动机结构,主要被应用在多模式串的文本匹配问题中.理解AC自动机,首先要熟悉KMP算法和字典树.使用KMP可以分开对每个模式串进…
P3808 [模板]AC自动机(简单版) [题目描述] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. #include<bits/stdc++.h> using namespace std; typedef long long LL; const int INF=1e9+7; inline LL read(){ register LL x=0,f=1;register char c=getchar(); while(c<48||c>57){if(c=='-')f=…
题目:P3808:https://www.luogu.org/problemnew/show/P3808 P3796:https://www.luogu.org/problemnew/show/P3796 从这里学了下AC自动机:http://www.cnblogs.com/cjyyb/p/7196308.html 我的理解大概就是构建一棵由模式串组成的 Trie 树,然后把文本串一节一节放在上面查找: 失配指针指向的是结尾字母和自己一样的.Trie 树上的其他分支,大约就是在找后缀这样的感觉:…
题目背景 这是一道简单的AC自动机模版题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 输入输出格式 输入格式: 第一行一个n,表示模式串个数: 下面n行每行一个模式串: 下面一行一个文本串. 输出格式: 一个数表示答案 输入输出样例 输入样例#1: 2 a aa aa 输出样例#1: 2 说明 subtask1[50pts]:∑length(模式串)<=10^6,len…
嘟嘟嘟 这个和某谷的AC自动机模板简单版差不多. 但还是要注意几点的: 1.这个是统计出现次数,而不是是否出现,所以在查询的时候加上这个节点的val后,不能把val标记为-1.那么也就可以说查询的时间复杂度能比简单版的稍微第一慢一点. 2.考虑k个一样的模式串:刚开始我想的是每一个节点开一个vector,记录这里是第几个模式串.但其实没有这个必要,对于相同的模式串,我们只用记录任意一个就行,反而在出现次数上要都加上.因为如果主串中存在这些相同的模式串,那么出现次数应该是出现次数 * k.输出的时…
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 输入输出格式 输入格式: 第一行一个n,表示模式串个数: 下面n行每行一个模式串: 下面一行一个文本串. 输出格式: 一个数表示答案 输入输出样例 输入样例#1: 复制 2 a aa aa 输出样例#1: 复制 2…
传送门 解题思路 AC自动机,是解决多模匹配问题的算法,是字典树与kmp结合的算法,可以解决许多子串在文本串中出现的次数等信息.关键是实现一个fail指针,是指向更靠上的前缀相同字母,从而可以实现在文本串中跳的操作. 代码 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; co…
P3796 [模板]AC自动机(加强版) https://www.luogu.org/problemnew/show/P3796 题目描述 有NN个由小写字母组成的模式串以及一个文本串TT.每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串TT中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据. 每组数据的第一行为一个正整数NN,表示共有NN个模式串,1 \leq N \leq 1501≤N≤150. 接下去NN行,每行一个长度小于等于7070的模式串.下一行是一个长度小…
[算法模版]AC自动机 基础内容 板子不再赘述,OI-WIKI有详细讲解. \(query\)函数则是遍历文本串的所有位置,在文本串的每个位置都沿着\(fail\)跳到根,将沿途所有元素答案++.意义在于累计所有以当前字符为结尾的所有模式串的答案.看代码就能很容易的理解. 另外\(e[i]\)记录的是第\(t\)个模式串结尾是哪个节点(所有节点均有唯一的编号). 贴个P5357 [模板]AC自动机(二次加强版)板子: #include<iostream> #include<cstdio&…
题目链接:https://www.luogu.com.cn/problem/P3796 AC自动机:复杂度$O( (N+M)\times L )$,N为模式串个数,L为平均长度,M为文章长度. insert: 构造一个trie,然后标记一下每一个模式串的最后一个,即$vis$. get_fail: 进行在trie上进行BFS,第一层点的失配指针指向根节点:之后的一个节点失配指针指向/他父亲的失配指针/指向的节点中/的儿子具有相同节点的位置. 这里有一个小优化:fail是用来寻找失配时走到的位置的…
传送门:https://www.luogu.org/problem/P3808 题解:是一个AC自动机的裸题了,注释加在代码里面了 #include<bits/stdc++.h> using namespace std; const int maxn = 1e6 + 5, sigma_size = 26; int ch[maxn][sigma_size]; int tot; //结点总数 int ans = 0; int f[maxn]; //失配函数 int last[maxn];//表示…
Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 57353    Accepted Submission(s): 18820 Problem Description In the modern time, Search engine came into the life of everybody li…
题目 给n个字母,构成长度为m的串,总共有n^m种.给p个字符串,问n^m种字符串中不包含(不是子串)这p个字符串的个数. 将p个不能包含的字符串建立AC自动机,每个结点用val值来标记以当前节点为后缀的字符串是否包含非法字符串(p个字符串中的任何一个). 状态转移方程:f(i, j)  += f(i-1, k) f(i, j)表示长度为i的字符串,结尾为字符j,方程j和k的关系可以从自动机中失配关系直接获得(j是k的后继结点). 总之感觉是好东西,快存下来 大数模版: #include <cs…
题目背景 这是一道简单的AC自动机模版题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 输入输出格式 输入格式: 第一行一个n,表示模式串个数: 下面n行每行一个模式串: 下面一行一个文本串. 输出格式: 一个数表示答案 输入输出样例 输入样例#1: 2 a aa aa 输出样例#1: 2 说明 subtask1[50pts]:∑length(模式串)<=10^6,len…
Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 77903    Accepted Submission(s): 27032 Problem Description In the modern time, Search engine came into the life of everybody lik…
[题解]P3796 [模板]AC自动机(加强版) 记录当前\(cnt\)是第几个"星".记录第几个串是对应着第几个星. 这里补充一点对于\(AC\)自动机的理解.可能一直有个问题我没有想明白,就是打标记的点只有一个,然而匹配时,假若一个分支包括了另一个不同的分支该怎么办.实际上,我们可以在匹配的时候使用\(fail\)数组进行类似链式前向星的遍历,从而遍历到那个打标记的地方.那么问题来了,怎么保证链式前向星会遍历到那个打了标记的节点呢?答案就在\(gen\_fail\)的玄机里.\(g…
AC自动机笔记 0.0 前言 哇,好久之前就看了 KMP 和 Trie 树,但是似乎一直没看懂 AC自动机?? 今天灵光一闪,加上之前看到一些博客和视频,瞬间秒懂啊... 其实这个玩意还是蛮好理解的... 在这里先给一个样例,之后也都好举例子. 模式串: 5 FG HE HERS HIS SHE 匹配串:HISHERS 1.1 深度理解 KMP KMP 算法的精华部分即其处理的 Next 数组. Next 数组所存的数值即代表j之前的字符串中有最大长度为k 的相同前后缀. 记录这个有什么用呢?…
题目描述 有NNN个由小写字母组成的模式串以及一个文本串TTT.每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串TTT中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据. 每组数据的第一行为一个正整数NNN,表示共有NNN个模式串,1≤N≤1501 \leq N \leq 1501≤N≤150. 接下去NNN行,每行一个长度小于等于707070的模式串.下一行是一个长度小于等于10610^6106的文本串TTT. 输入结束标志为N=0N=0N=0. 输出格式: 对于每组…
原题链接 Description 模板题啦~ Code //[模板]AC自动机(加强版) #include <cstdio> #include <cstring> int const N=2e5; int const L=1e6+10; int n; char s1[200][80],s2[L]; int rt,ndCnt; int ch[N][26],val[N],fail[N],pre[N]; void ins(char s[],int id) { int len=strlen…
洛谷题目传送门 先膜一发yyb巨佬 orz 想学ac自动机的话,推荐一下yyb巨佬的博客,本蒟蒻也是从那里开始学的. 思路分析 裸的AC自动机,这里就不讲了.主要是这题太卡时了,尽管时限放的很大了...... 用传统方法匹配时,每走到一个新位置,都是要统计答案的.怎么统计呢?暴力跳\(fail\),把沿路上能够产生答案的算上,直到跳到根才停下来.这里的时间复杂度是 \(O(70N)\),在有多组数据的情况下其实是很吃亏的.(蒟蒻用了\(fread\),根据目测,最大的一个点输入大小在\(30MB…
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 输入输出格式 输入格式: 第一行一个n,表示模式串个数: 下面n行每行一个模式串: 下面一行一个文本串. 输出格式: 一个数表示答案 输入输出样例 输入样例#1: 2 a aa aa 输出样例#1: 2 说明 su…
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 输入输出格式 输入格式: 第一行一个n,表示模式串个数: 下面n行每行一个模式串: 下面一行一个文本串. 输出格式: 一个数表示答案 输入输出样例 输入样例#1: 2 a aa aa 输出样例#1: 2 说明 su…
所学的AC自动机都源于斌哥和昀神的想法. 题意:求目标串中出现了几个模式串. 使用一个int型的end数组记录,查询一次. #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxw = 50 * 10000 + 10; const int sigma_size = 26; const int maxl = 1000000 + 10; struct T…
题意:输出出现模式串的id,还是用end记录id就可以了. 本题有个关键点:“以上字符串中字符都是ASCII码可见字符(不包括回车).”  -----也就说AC自动机的Trie树需要128个单词分支. #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxw = 210 *500 + 10; const int sigma_size = 128; c…
完全忘了AC自动机怎么写了qwq,更别说AC自动机上DP了. 今天就好好地学习字符串好了qwq 提一下AC自动机的时间复杂度--设n是模式串的个数,m是文本串的长度,l是模式串的平均长度,那么它的时间复杂度就是\(O(n+m)*l\). AC自动机上fail指针指向的点,从root到它代表的是其后缀. 简单版:给定一个文本串,和多个模式串.求有多少个模式串在文本串中出现过.qwqwq #include<iostream> #include<cstring> #include<…
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 输入输出格式 输入格式: 第一行一个n,表示模式串个数: 下面n行每行一个模式串: 下面一行一个文本串. 输出格式: 一个数表示答案 输入输出样例 输入样例#1: 2 a aa aa 输出样例#1: 2 说明 su…
传送门 AC自动机的模板 简单的理解就是字典树上的KMP 注意数组不要开太大 不然每次memset耗时太多 有一个小优化 每次走 fail 边找匹配时只有一些会更新答案 那么就可以把没用的fail边压缩掉 设 g[x] 表示从 x 点一直走 fail 边,走到的第一个有结束标记的点 那么找匹配时就只有要 g 边 然后就是模板了 #include<iostream> #include<cstring> #include<cstdio> #include<cmath&…
Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 59827    Accepted Submission(s): 19715 Problem Description In the modern time, Search engine came into the life of everybody lik…
如果你想要做出这道题,你需要先了解两个知识点: 1.字典树的构造 2.KMP算法(也就是fail指针的构造) 对于字典树,可以看看这个大佬: https://www.cnblogs.com/TheRoadToTheGold/p/6290732.html 对于KMP,可以看看这个大佬: https://www.cnblogs.com/SYCstudio/p/7194315.html#4255259 (强烈推荐!!!!) 代码实现步骤:(前两个步骤是AC自动机的必备) 1.利用所提供的模式串构造字典…
每次匹配都不停跳fail显然太慢了,于是在每个节点和fail指向的点连一条边,构成一棵树,在这棵树上差分一下就好了. AC自动机 就这个算法而言其实没用想象中那么难. #include <cstdio> #include <queue> #include <cstring> using namespace std; struct Node{ int fail, next[26], num; }AC[200010]; int n, u, cnt; queue <in…