![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
ac自动机
Ayews
CST freshman
展开
-
hdu4511 小明系列故事——女友的考验 [kuangbin专题-ac自动机]
这道题需要我们将路径表示成字符串形式,再构造fail指针。需要注意的是开始位置是1号点,也就是ch[0][0],而不是根节点。当然如果给的路径中不含一号点,那可以理解成从根结点出发。dp数组保存需要走的最长路径。#include <bits/stdc++.h>#include <iostream>#include <cstdio>#include <queue>#include <map>#include <cstring&g原创 2020-09-13 21:57:59 · 740 阅读 · 0 评论 -
hdu4758 Walk Through Squares [kuangbin专题-ac自动机]
这道题看起来神乎其神,实际上只是上一道题弱化版的弱化版。。只要构造一个目标串,包含两个输入串就行了。dp[i][j][k][h],i跟j表示当前所在位置,k表示所在字典树节点,h表示两个字符串是否存在的状态(即0,1,2,3,分别表示都不存在,存在1号,存在2号,存在两个)。然后就是简单dp。#include <bits/stdc++.h>#include <iostream>#include <cstdio>#include <queue>#i原创 2020-09-13 21:54:21 · 144 阅读 · 0 评论 -
hdu3247 Resource Archiver [kuangbin专题-ac自动机]
这道题也很有意思,综合了ac自动机,dp与最短路。本题要求构造出包含所有Resource串,且不含任何的病毒串。不含任何病毒串可以转换成不能走到字典树上某个节点,所以很自然的可以想到本题的关键是从一个resource串转移到另一个需要的最短的新增长度。结合字典树,从一个串转移到另一个串,是不是就可以理解成从前一个串的最后一个字符指向的节点走到后一个串的最后一个字符所指向的节点?这样就在某种程度上转化成了tsp问题。我们先用最短路算法求出所有resource串转移到另一个resource串需要的步骤,就是在字原创 2020-09-13 21:49:55 · 291 阅读 · 0 评论 -
hdu3341 Lost‘s revenge [kuangbin专题-ac自动机]
这题也很有意思,不只是单纯的要构造出含输入字符串最多的字符串,单个字符还有数量上限。题目的说法是对原字符串进行重新安排,但具体怎么安排,以及操作次数这些是没说的,所以我们可以理解成直接重新构造字符串,并且每个字符出现的次数不能超过原字符串中它出现的次数。这道题中的字符只含ACTG,简化了问题。最终构造出的字符串长度小于40,但如果对ACTG每个字符都开40的大小,那需要404040*40的空间,显然不可能,但我们注意到这四个字符加起来最多也只能出现40次,所以考虑状压,用一维保存这四个字符出现的次数。考原创 2020-09-13 21:06:39 · 103 阅读 · 0 评论 -
zoj3228 Searching the String [kuangbin专题-ac自动机]
这题考察对ac自动机深一步的使用。我们知道在利用ac自动机进行模式匹配时,是依据是否到达模式串最后一个字符对应的节点来判断是否出现的,因此是允许模式串相互重叠的。然而这一题出现了新的要求,输入数据会指定串能不能重叠,因此我们还需要保存一下每个串上次出现的位置,来判定是否存在重叠。这里需要额外注意一个事情,就是说可能会出现两个相同串的不同询问,一次询问重叠,一次不重叠,因此insert时还需要处理一下这个情况,将第二次出现的串标记一下,并将它的id赋值为它第一次出现时给的id。#include <b原创 2020-09-13 20:21:33 · 113 阅读 · 0 评论 -
hdu2457 DNA repair [kuangbin专题-ac自动机]
很有意思的一道题,这次在dp的基础上加了修改,要求最少改几次。dp[i][j]表示当前处理到了第i个字符,所在节点为j,需要修改的次数。注意到一件事情,dp[i][j]可以指代原串的前i位经过修改,到达了字典树上的j节点。在dp状态转移时,我们要保证修改后的串不含输入的若干字符串,所以这些串结尾对应的节点我们是不能走的。其他节点都可以走,那么当原串的i+1位与我们要放的字符k不一样时,dp值+1,就可以视作进行了一次修改,到达了ch[j][k]节点了。当然如果原本就没有包含输入的字符串,不修改的状态也会原创 2020-09-13 20:14:00 · 105 阅读 · 0 评论 -
hdu2296 Ring [kuangbin专题-ac自动机]
比较常规的ac自动机结合dp的题,但这道题要求最后输出构造的字符串,我保存了一堆string。。总觉得不甚美观。具体写法就是先插入字符串,构造fail指针,然后开始dp。dp[i][j]表示当前构造长度为i,所在的节点为j,能得到的最大的value。同时保存对应的字符串。注意需要字典序最小,所以得另外判一下。需要注意的一点是题目的额外要求,如果存在多个value相同的串,优先长度最短,因此最后输出答案时我们得先找到value的最大值,同时保存最短的串的长度,之后只要找一下这个长度的值为最大值的字典序最小原创 2020-09-13 20:00:00 · 152 阅读 · 0 评论 -
hdu2825 Wireless Password [kuangbin专题-ac自动机]
专题中第一道涉及状压dp的题。这道题相比前两题有个区别,这次是要至少包含k个字符串了,因此我们最后还要找出那些包含大于等于k个字符串的状态。状压原理跟之前学习笔记里提到的一样,给字符串一个编号id,那么标记数组在下标为这个字符串在状态转换图里的结尾位置的节点的值就为1<<id,然后在构建fail指针时逐层取或,这样就能让每个节点记录下它与它能通过fail指针到达的节点所指代的字符串。同时,这个值的二进制形式中1的个数就是包含的不同字符串的数量。#include <bits/stdc+原创 2020-09-13 19:37:35 · 97 阅读 · 0 评论 -
poj1625 Censored! [kuangbin专题-ac自动机]
有点毒瘤的一道题…这题也是求不含若干个串的长度为m的字符串的个数,但数据会超longlong,因此之前的矩阵快速幂的方法做不了,只能用dp做。ac自动机与dp结合的非常频繁,就当开个头吧。#include <iostream>#include <cstdio>#include <queue>#include <map>#include <cstring>#define fi first#define se second#def原创 2020-09-11 15:45:39 · 143 阅读 · 1 评论 -
hdu2243 考研路茫茫――单词情结 [kuangbin专题-ac自动机]
在做这题前建议先做下poj2778poj2778本题跟poj2778有点类似,他是求不含模式串,长度为n的字符串的个数,本题是求至少包含一个,那么很简单,求出总数,再将不含模式串的数量减去即可。有一些细节需要注意,首先本题的mod是2^64,所以我们把数据开ull即可。然后求总数的话也需要借助矩阵快速幂,线性递推的时间复杂度也是不可接受的。另外,本题还涉及到求和,所以状态转移矩阵中需要增加一维,第L+1列全部为1。#include <bits/stdc++.h>#include <原创 2020-09-11 13:22:58 · 120 阅读 · 0 评论 -
poj2778 DNA Sequence [kuangbin专题-ac自动机]
神题。我在前面的ac自动机学习笔记里曾提过,ac自动机的本质就是构造出一个状态转换图,模式匹配的过程实际上就是在图上进行状态转移。构造出一个长为n的字符串,实际上就相当于在状态转换图上从根节点开始走n步,求所有方案数。而本题中有若干个串不能出现在目标字符串中,换句话说其实就是状态转换图中对应的这些字符串的终点所在的节点不能被走到,即不可达。当n很小时,我们可以借助dp来解决这个问题。dp[i][j]表示当前字符串长度为i,所在的状态转换图中节点为j,转移方程为dp[i+1][ch[j][k]] += d原创 2020-09-11 13:14:02 · 146 阅读 · 0 评论 -
hdu3065 病毒侵袭持续中 [kuangbin专题-ac自动机]
还是裸题。这次需要统计每个特征码出现的次数。#include <bits/stdc++.h>#define fi first#define se second#define FIN freopen("in.txt","r",stdin)#define FIO freopen("out.txt","w",stdout)#define INF 0x3f3f3f3f#define per(i,a,n) for(int i = a;i < n;i++)#define rep(i,原创 2020-09-11 12:43:05 · 99 阅读 · 0 评论 -
hdu2896 病毒侵袭 [kuangbin专题-ac自动机]
差不多也是裸题,将病毒特征码插入到字典树后对每个网站源码query一遍即可。当然要记得去重。#include <bits/stdc++.h>#define fi first#define se second#define FIN freopen("in.txt","r",stdin)#define FIO freopen("out.txt","w",stdout)#define INF 0x3f3f3f3f#define per(i,a,n) for(int i = a;i <原创 2020-09-11 12:40:00 · 138 阅读 · 0 评论 -
hdu2222 Keywords Search [kuangbin专题-ac自动机]
ac自动机裸题,可以拿个板子走#include <bits/stdc++.h>#define fi first#define se second#define FIN freopen("in.txt","r",stdin)#define FIO freopen("out.txt","w",stdout)#define INF 0x3f3f3f3f#define per(i,a,n) for(int i = a;i < n;i++)#define rep(i,a,n) for原创 2020-09-11 12:34:22 · 117 阅读 · 0 评论