自动机

AC自动机 洛谷P3796 模板

寵の児 提交于 2019-11-27 20:35:11
题目链接: https://www.luogu.org/problem/P3796 题意:给多个模式串和一个文本串,要求出模式串匹配最多的次数是多少,并输出这些次数的模式串。 分析:求匹配次数很明显,把AC_qurey函数稍微改一下就好,但要输出这些模式串我就迷了,当时认为Trie只能上到下,到了一个结点无法回到其上的结点,就不会了,事实上还是很浅显,另外用一个数组记录位置就好了啊。。。。将字典树结点中的end改为只有其是一个单词的结尾才做标记,并且标记这个单词的次序。 clean函数应该就是AC自动机里的初始化了,因为不知道会用到多少边,故是每当cnt增加了(即出现了新的一条边)的时候我们再初始化 #include<bits/stdc++.h> using namespace std; const int maxn=1e6+10; const int inf=0x3f3f3f3f; typedef long long ll; #define meminf(a) memset(a,0x3f,sizeof(a)) #define mem0(a) memset(a,0,sizeof(a)); struct result{ int num,pos; }ans[200]; bool cmp(const result &a,const result &b){ if(a.num==b.num)

AC自动机练习2:修改串

删除回忆录丶 提交于 2019-11-27 19:28:05
这道题的话用到了dp,一个比较简单的dp方程 1466: 【AC自动机】修改串 poj3691 时间限制: 1 Sec 内存限制: 128 MB 提交: 18 解决: 14 [ 提交 ] [ 状态 ] [ 讨论版 ] [命题人: admin ] 题目描述 【题意】 给出n个模式串,然后给出一个修改串,求尽量少修改修改串,使得修改串不含有任何一个模式串,不能的话输出-1 每个串只有'A','C','G','T'四个字母 【输入格式】 有多组数据,输入以一个0结束 每组数据: 输入一个n(n<=50) 接下来n行输入n个模式串(每个模式串长度不超过20) 最后一行输入修改串(长度不超过1000) 【输出格式】 输出Case T: ans T当前输出的是第T组数据,ans表示最少修改次数,不能修改则ans=-1 【样例输入】 2 AAA AAG AAAG 2 A TG TGAATG 4 A G C T AGT 0 【样例输出】 Case 1: 1 Case 2: 4 Case 3: -1 我第一眼看到这道题的时候,一度怀疑是 模板题 ,然后定睛一看,没这么简单,应该我们在修改的时候要尽可能的找位置去修改更多的字符,所以这就意味这我们可能要用到最方便的继承状态的dp(当然作为一个dp盲人,我一开始是没有想到的,只有暴力才是王道),下面看一下讲解 说难的话就不能说特别难

AC自动机 洛谷P3808 模板

∥☆過路亽.° 提交于 2019-11-27 19:18:41
题目链接: https://www.luogu.org/problem/P3808 题意:给n个模式串和一个文本串,求有多少个模式串在文本串中出现过 AC自动机的裸题,AC自动机最难理解的地方在于fail指针,这里借用了博客 https://blog.csdn.net/creatorx/article/details/71100840#commentBox 以及 https://www.cnblogs.com/cjyyb/p/7196308.html 的部分讲解 然后这个博客图很多,讲的很清楚: https://www.luogu.org/blog/hicc0305/solution-p3808 f a i l 是失配指针,注意是失配 意味着,如果我此时匹配失败,那么,我们就要到达这个指针指向的位置继续尝试匹配 所以,我们可以将失配指针指向的的节点理解为: 当前节点所代表的串,最长的、能与后缀匹配的,在 T r i e Trie中出现过的前缀所代表的节点。 所以, f a i l 指针类似于 k m p 的 n e x t 数组,只不过由单串变为了多串而已。 举例:插入abcd, bce, abd, cd,构建字典树 首先我们让与根节点直接相连的节点的fail直接指向root,为了让你更好的理解fail指针,我们以节点x,y,z为例

AC自动机练习题1:地图匹配

旧时模样 提交于 2019-11-27 15:31:57
AC自动机板子 ,学习之前要是忘记了就看一下 1465: 【AC自动机】地图匹配 poj1204 时间限制: 1 Sec 内存限制: 256 MB 提交: 78 解决: 46 [ 提交 ] [ 状态 ] [ 讨论版 ] [命题人: admin ] 题目描述 【题意】 给出有一个L*C的字符地图,地图的行与列都从0开始编号 然后给出一些字符串,求出这些字符串在字符地图上第一次出现的坐标 输出字符串第一个字母的坐标和字符串的方向 字符串的方向是指字符串的走向 A表示正北,B表示东北,C表示正东,D表示东南,E表示正南,F表示西南,G表示正西,H表示西北 且保证字符串的方向是固定的 【输入格式】 第一行输入L,C,W(0<L,C,W<=1000) L表示行数,C表示列数,W表示字符串的数量 然后输入L*C的字符矩阵 最后输入W行字符串 【输出格式】 输出W行,每行对应第i个字符串第一个字母的坐标和字符串的方向 【样例输入】 20 20 10 QWSPILAATIRAGRAMYKEI AGTRCLQAXLPOIJLFVBUQ TQTKAZXVMRWALEMAPKCW LIEACNKAZXKPOTPIZCEO FGKLSTCBTROPICALBLBC JEWHJEEWSMLPOEKORORA LUPQWRNJOAAGJKMUSJAE KRQEIOLOAOQPRTVILCBZ

【AC自动机】Censoring

匆匆过客 提交于 2019-11-27 14:11:55
【题目链接】 https://loj.ac/problem/10059 【题意】 有一个长度不超过 1e5 的字符串 。Farmer John 希望在 T 中删掉 n 个屏蔽词(一个屏蔽词可能出现多次),这些词记为 P1,P2……Pn 。 【题解】 利用栈来进行匹配删除即可。 1、建模式串的AC自动机。(结尾位置记录长度) 2、利用文本串跑一遍AC自动机。 3、在跑的过程中,如果遇到屏蔽字的结尾时,相应操作为:1、把栈里弹出模式串的长度,2、同时文本串继续跑。 4、跑的过程中还需要一个辅助的数组记录当前是 匹配到文本串的在AC自动机上的下标。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N = 1e5+100; 6 char S[N],T[N]; 7 int Trie[N][26],fail[N],End[N]; 8 int n,Ans[N],Back_up[N],top,idx=1; 9 int Q[N],Head,Tail; 10 void Insert( char s[] , int Id ){ 11 int len = 0 , p = 1 ; 12 13 for(int i=0;s[i];i++,len++){ 14 int t

【AC自动机】玄武密码

非 Y 不嫁゛ 提交于 2019-11-27 14:11:31
【题目链接】 https://loj.ac/problem/10058 【题意】 对于每一段文字,其前缀在母串上的最大匹配长度是多少呢 【参考别人的题解】 https://www.luogu.org/problemnew/solution/P5231 我们只需要先建立所有密码的trie树 再以母串为主串跑一个AC自动机 不过其中还是有一些需要改动的地方 原本字典树中用来记录某个节点是不是字符串结尾的数组不需要,直接删去 我们需要另一个数组来标记哪些点被匹配 跑完ac自动机后从trie树上找最后一个匹配的点即可 优化:由于nxt数组是递归到0的所以只要有一个点被标记过,那么这个点到0的所有点都已经被遍历过直接退出即可 【自己理解】 其实这个题目就是套路。 1、建模式串的AC自动机。 2、利用文本串跑一遍AC自动机,把对应的位置标记上。 3、再跑一遍模式串,去最长的位置就是答案了。 【代码】 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int M = 2e7 + 5 ; 6 const int N = 2e5+5 ; 7 char T[M]; 8 char P[N][205]; 9 int Trie[M][4],Match[M],fail[M]

关于字符串与AC自动机算法

强颜欢笑 提交于 2019-11-27 12:38:46
相信大家都多少了解字符串 先大概说一说两种常用字符串的类型: 1.str:string; 2.str:ansistring; string类型,长度为255,一般处理较短的字符串,而ansistring类型,则大概有2G,用来处理比较大的数据,当然,ansistring类型也可以由一个庞大的字符数组代替。 字符串的常用函数和过程列表: 函数和过程名 作用 copy(a,b,c) 取a串中从第b个字符开始的c个字符 length(a) 获取a串的长度 pos(a,b) 在b串中找字串a str(a,b) 把整数a转成字符串并存入b串中 val(a,b) 把字符串a转化成数字并存入整数b内 delete(a,b,c) 删除串a中从第b个字符开始的c个字符 insert(a,b,c) 在串字符位置插入子串c upcase(a) 将字母a转换成大写字母 用初级 到爆 的题举个例子 求输入英文句子单词的平均长度 每行一个输出 相信大家都会做, 完整代码如下: Var n:longint; s:string; Begin readln(n); for i:=1 to n do Begin readln(s); l:=l+length(s); end; write(l div n);//假设都可以除尽 end. 每一道字符串的题都会有一个容易出错的问题——输入。 许多 连这道题都出错的

AC自动机

青春壹個敷衍的年華 提交于 2019-11-27 11:55:39
版权声明:本文为CSDN博主「bestsort」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。 原文链接: https://blog.csdn.net/bestsort/article/details/82947639 出自bestsort.cn 文章非博主原创 要学AC自动机需要自备两个前置技能:KMP和trie树(其实个人感觉不会kmp也行,失配指针的概念并不难) 其中,KMP是用于一对一的字符串匹配,而trie虽然能用于多模式匹配,但是每次匹配失败都需要进行回溯,如果模式串很长的话会很浪费时间,所以AC自动机应运而生,如同Manacher一样,AC自动机利用某些操作阻止了模式串匹配阶段的回溯,将时间复杂度优化到了O(n) (n)为文本串长度 下面开始用图学习ac自动机吧(个人比较喜欢放图,能用一张图解决的绝不叨叨) 首先给定模式串"ash","shex","bcd","sha",然后我们根据模式串建立如下trie树: 然后我们再了解下一步: ac自动机,就是在tire树的基础上,增加一个fail指针,如果当前点匹配失败,则将指针转移到fail指针指向的地方,这样就不用回溯,而可以路匹配下去了.(当前模式串后缀和fail指针指向的模式串部分前缀相同,如abce和bcd,我们找到c发现下一个要找的不是e,就跳到bcd中的c处

蒟蒻林荫小复习——AC自动机

自闭症网瘾萝莉.ら 提交于 2019-11-27 08:46:33
AC自动机:Aho-Corasick automaton,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法。 今天蒟蒻林荫来复习AC自动机 前置芝士 KMP算法 TRIE树(这个不会的话出门右转幼儿园) 好吧我承认AC自动机要比KMP好理解。 如何建立一个AC自动机 建立一颗字典树,其中插入操作和普通字典树的一模一样 在字典树上构造fair数组(这也就是AC自动机与KMP联系起来的地方) 开始查找 如何构造一个fair数组?/fair数组是个啥? fair数组与KMP中的next一样都是作为失配数组存在的,而对于节点X,fair所存的元素是fair[x的父亲]的一个与X相同的儿子,如果没有fair指向root。 也就是说fair[x]=某个与x节点相同的点或者root,并且fair[x]所在的链一定存在于X所在的这条链上,换句话说,fair[x]所跳转到的字符串一定是X所在串从X向前的一部分,且一定包括X。 至于如何求fair,就通过BFS来实现 下面来张图 红色线:root出队,将h和s两个点fair置为root,并将h和s入队 蓝色线:h出队,子节点e的fair等于自己父亲的fair的子节点中e的位置,不存在所以为root,e入队,同时s出队,子节点a的fair为自己父亲的fair的子节点中a的位置不存在为root,a入队

算法学习:AC自动机

青春壹個敷衍的年華 提交于 2019-11-26 14:20:59
【定义】 【自动机】 由 状态集 ,初始状态集 ,终止状态集 ,字母集 ,对应关系 五个元素组成的结构       可以简单的将 状态集 理解为 结点 , 初始状态集 理解为 初始点 , 终止状态集 理解为 终点 字母集 理解为一个状态能够拥有的 出边的最大个数 ,而在自动机中,特殊的是,一个结点的所有出边必须都要存在 例如在AC自动机中,每个节点都必须要有26个字母的出边所指向的节点 对应关系,可以理解为连通的边,例:节点 u 的 ’a‘ 的出边能够到达节点 v ,这就是一组对应关系 注:自动机的概念不用知道也可以学自动机,但是个人感觉理解了自动机的含义,更容易去明白他的本质 而且后面学其他自动机也更容易理解 【模式串】 一个比较短的串,需要找 文本串上有多少个他 【文本串】 一个比较长的串,需要在 他上面有多少个模式串 【前置知识】 【trie树(字典树)】 从根节点插入一个字符串,依次插入 【KMP】 单文本 logn 复杂度内查找模式串出现次数 【强烈建议看最后的扩展】 【解决问题】 多个模式串匹配文本串 给定一个较长串为文本串,给定多个模式串,询问这两者的关系 (也有可能不只有一个文本串) 一般为出现次数什么的 【算法思想】 这个自动机的优点和KMP类似,所以有的博客中也会说,这是一个树上KMP。 KMP的优点在于有next数组作为指针失配时的指针