ACM字符串问题
HZ-VUW
这个作者很懒,什么都没留下…
展开
-
KMP题目分析与总结
前言本篇文章不阐述KMP算法流程与实现方式,网上有很多对KMP算法进行详细阐述的文章,至于KMP的实现方式,特别推荐刘汝佳版本的KMP算法,简单易懂且易于实现。 本篇文章主要针对常见的KMP问题进行剖析,提供一些思路供反思、参考、交流。KMP能够解决的问题KMP可以有效解决大部分单匹配问题,KMP算法的复杂度是O(M+N),这是十分高效的。KMP核心问题——F数组(NEXT数组)F数组是整个KMP原创 2017-07-30 21:52:01 · 1090 阅读 · 0 评论 -
HDU 3613 Manacher算法
题意有一串字符,将其切成两串,如果一串是回文的,那么便是这个回文串所有的元素值累加。如果不是回文的,那么值便是0。问最大可获得的值是多少。题解Manacher模板套上去,记录一下前缀回文和后缀回文。枚举切割点,求最大值。代码#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vecto原创 2017-09-04 21:12:19 · 296 阅读 · 0 评论 -
HYSBZ 2565 Manacher算法
题意中文题,不解释题解这道题正解应该是回文树,不过用Manacher算法8s水过了。首先用Manacher算法算出来P数组,然后将所有的P数组-1,这样的话便能得到以某一个位置为中心的回文串最长长度。然后我们可以根据这个长度为两个端点赋值。dp1[i]代表从i-1开始向前的最长回文子串,dp2[i]代表从i+1开始最长回文子串。我们可以在i这个位置,得到(dp2[i-p[j]],dp1[i+p[j]原创 2017-09-04 22:56:32 · 322 阅读 · 0 评论 -
SPOJ REPEATS 后缀数组
题意给一个字符串,要求寻找一个循环子串,使得循环子串的循环次数最大.题解感觉这道题确实有不小的难度,尤其是对于刚刚接触后缀数组的来说,确实很难处理.既然很难处理,那我们就可以先用最暴力的方法解决,如果暴力有哪里难以解决的话,再去考虑后缀数组优化. 既然是要找一个循环子串,那么我们可以枚举长度(很常见的字符串套路).从0开始,计算从某一位开始向后组成的最大循环次数.可以明显看出,这个算法是O(N^2原创 2017-08-27 23:01:56 · 282 阅读 · 0 评论 -
POJ 3504 HASH
题意一堆字符串由许多个单词组成,但是除了单词的开始和结尾都做了一定程度的乱序。要求破解这个被打乱的句子。题解HASH+DP(暴力)。首先对单词进行处理,将单词去掉头和尾记录到头和尾组成的哈希表中。对于长度为1的单词特殊记录。然后进行暴力搜索(DP)。暴力搜索从0开始,0可能是从0开始到0-100区间内组成的任意一个的单词的字符(因为单词长度最大为100,这个需要特别注意,会不会TLE就看这个了)。于原创 2017-08-28 12:16:29 · 299 阅读 · 0 评论 -
SPOJ NSUBSTR 后缀自动机+DP
题意给一个长度为S的字符串,问长度为1-S的子串最多出现了多少次。题解DP其实是非常简单的。。。主要就是一个后缀自动机的模板,敲对了就行。至于算法,认真观察后缀自动机,对后缀自动机理解透彻了就发现这是一道模板题。对于这道题,我发现的规律就是,对于一个点我们很容易算出来出现次数,然后的话我们可以看一下这个点对应的字符串最长长度是多少,那么小于等于这个长度的所有字符串出现次数最少为这个点的出现次数(RT原创 2017-09-13 22:38:15 · 333 阅读 · 0 评论 -
CodeForces 86C AC自动机
题意需要组成一个长度为N的字符串,要求组成的字符串每一位在这个字符串中能找到一个子字符串,这个子字符串属于一个字符串集合,这个集合有M的字符串。问有多少种组成方案。题解这道题很复杂,尤其是它是按子串组合来计算种类的,比如说样例给的那种情况,两个字符串相同,但是是两种不同的组合方案,所以我们计算的时候也算了两种。 如果我们按照以往的DP方案,开一个二维数组,dp[len][pos]的话,我们发现很难原创 2017-09-16 20:38:46 · 465 阅读 · 0 评论 -
HDU 4622 后缀自动机
题意一个字符串,问一段区间内的不重复子串有多少个。关于后缀自动机这道题基本上算是后缀自动机的模板题了。但是后缀自动机看了好久,刘汝佳在那本紫书中提到了三个数据结构的难点,现在看来后缀自动机算是第二难的。(毕竟可持久化平衡树有rope) 后缀自动机的话,网上有很多教程,但是即便教程很多,后缀自动机也依然很难。这里强烈推荐fanhq后缀自动机教程 这篇教程将后缀自动机的构建转化成了后缀树的构建,这样原创 2017-09-08 20:46:48 · 340 阅读 · 0 评论 -
CodeForces 696D AC自动机+DP+矩阵快速幂
题意给一组字符串,每个字符串有一个值,如果一个字符串包含这个子串,那么总值就加上这个子串的值。给一个长度,问能组成的最大值。题解对于要求长度1000的情况,我们可以直接DP。但是这道题不 行,这道题长度达到了10^16。我们考虑用矩阵快速幂加速。 我们很容易便能得到一个状态转移方程,dp[i][j]=max(dp[i][j],dp[i][k]+dp[k][j])。这个状态转移方程中的I,J,K都原创 2017-09-09 23:16:11 · 350 阅读 · 0 评论 -
HDU 6194 后缀自动机(2017 ICPC沈阳网络赛A题)
题意给一个字符串,问出现K次的子串有多少个。题解其实是后缀自动机的模板题。。后缀自动机有个right数组,记录的就是从1开始到这个点组成的子串的出现次数。了解了这个以后,从1开始DFS记忆化搜索一下就可以了。代码#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #in原创 2017-09-10 21:56:55 · 885 阅读 · 0 评论 -
POJ 1743 后缀数组(男人八题七)
题意有一串音符,输出最长的两个不重叠的相似串的长度(如果小于5,则输出0)。相似的意思是两个串所有字符之差必须一样。题解很有意思的一道题。据说可以用HASH做,但是HASH看了半天都没看懂,只能用后缀数组了。 刚看到相似的时候我吓了一跳,不过如果转化成字符之差的话就舒服多了。我们可以用后一个字符减去前一个字符,这样可以得到一个差序列。如果两个差序列相等,则可以认为两个串相似。 对于这种找最长字符原创 2017-09-02 11:59:20 · 224 阅读 · 0 评论 -
SPOJ LCS2 后缀自动机
题意给多个字符串,问最长公共子串。题解最长公共子串用后缀自动机还是很方便的,首先的话,有一个非常重要的后缀自动机性质一定要明确,后缀自动机一个点的par一定是这个点代表的所有字符子串的公共后缀。了解了这一点,我们便可以构造后缀自动机,然后进行匹配。 在匹配的过程中,如果可以成功转移,直接转移并且把记录的长度++就可以了。如果不可以成功转移,那么就需要去进行失配匹配。这时候后缀自动机的方便性就很好的原创 2017-09-11 23:32:48 · 304 阅读 · 0 评论 -
UVALive 7043 字典树+DFS
题意分配子网,给一个子网地址,求出除了这个子网地址以外的所有子网地址。题解裸的字典树。只不过在子网地址记录上有一些技巧,因为子网地址恰好可以用32位整数表示,所以可以用一个unsigned int 进行状态压缩,这样就不用去搞字符串进行记录了。ORZ。。 至于寻找子网地址,在字典树上进行DFS,如果某个节点的子节点都不存在(比如说字典树为空的情况),那么就记录这个节点的状态。如果某个节点的某个子节原创 2017-08-15 21:23:28 · 280 阅读 · 0 评论 -
SPOJ DISUBSTR 后缀数组
题意有T个字符串,问每个字符串有多少不同的子串。题解后缀数组模板题,基本上模板套上去就能AC。当然了,还是有点变化的。关于后缀数组的题,首先观察Height特征。 可以发现,字符子串数量之和即为后缀长度之和。不过,子串有重复的,需要去重。观察height数组就会发现,height数组记录的就是两个后缀之间重复的前缀数量。因此后缀长度-height求和就可以了。注意事项第一次写后缀数组,忘记加尾原创 2017-08-25 12:09:00 · 227 阅读 · 0 评论 -
POJ 1816 字典树+DFS
题意类似正则匹配,*匹配0-n个字符,?匹配1个字符。给一个字符串,问哪几个匹配表达式能匹配这个字符串。题解如同AC自动机和DP完美结合一样,字典树和DFS也是完美结合。针对每一个字符串,结合字典树进行DFS。DFS深搜的时候,对?和*的情况进行特殊处理,如果存在?节点,则字符串匹配位置向后移动一位。如果存在*节点,则字符串匹配位置向后移动一位,或者不移动。由于*可以匹配多个字符,因此对于*允许持续原创 2017-08-16 11:17:01 · 378 阅读 · 0 评论 -
UVA 11732 链式字典树
题意给一些字符串,问如果使用strcmp函数对这些字符串两两比较,需要进行多少次字符比较。(strcmp函数在题目中已给出,如果字符相等,则还需要将该字符与’\0’进行比较)题解链式字典树我自己的叫法,网上大多数题解都把这种字典树叫做左儿子,右兄弟的字典树,但是这种叫法感觉会引起误解。一开始我以为右兄弟是根的兄弟,后来才意识到右兄弟是左儿子的兄弟。 具体效果见下图。 可以看到,这样存储只需要原创 2017-08-16 15:21:04 · 401 阅读 · 0 评论 -
HDU 2243 AC自动机+矩阵快速幂
题意中文题,不解释题解这道题其实和POJ 2778是一样的,只是需要对矩阵有着更深刻的理解而已。我们很容易便能像POJ 2778一样求出来不包含条件字符串的字符串方案。只是题目中要求长度小于等于L,所以我们可以在矩阵中手动加一个点,这个点允许从任何状态转移而来。这点的意义表示字符串终止。也就是说如果字符串转移到这个点时候小于L,那么字符串最终长度小于L。求出来小于等于L,不包含条件字符串的方案数以后原创 2017-08-10 12:27:22 · 272 阅读 · 0 评论 -
HDU 2825 AC自动机+状压DP
题意给M个字符串,要求组成一个长度为N的字符串,至少包含K个给定字符串。题解利用AC自动机,我们可以进行状态转移, 以及模板匹配。要求目标串长度为N,且包含K个给定字符串。所以可以在包含给定字符串的AC自动机上进行状态转移。 dp[i+1][u][last[u]|s]=(dp[i+1][u][last[u]|s]+dp[i][j][s])%MOD; dp[i][j][k]表示,第i步,在j节点,原创 2017-08-10 18:27:44 · 242 阅读 · 0 评论 -
HDU 3247 AC自动机+状压DP
题意一个N个资源串,M个病毒串。要求生成一个字符串,包含所有资源串,但不能包含病毒串。问生成字符串的最小长度。题解首先利用AC自动机求出资源串的状态转移关系,因为资源串最多只有十种,因此可以进行状态压缩。在利用AC自动机求失配关系的时候(这里在求失配关系的时候需要将不存在的边补上),顺便求出来状态包含关系。 求出失配关系以后,首先要将所有的包含资源串的点加入到一个集合中,针对每个点进行BFS,计算原创 2017-08-12 21:31:39 · 345 阅读 · 0 评论 -
HDU 4057 AC自动机+状压DP
题意有一些字符串有权值,生成长度为L的字符串,问最大权值。如果最大权值为负,则输出“No Rabbit after 2012!”。题解也没太多好说的,算是基础的AC自动机+DP吧。主要是每个字符串只计算一次权值比较坑。最开始的时候,我是把这些权值记录到一个结构体内,在DP的时候进行计算。但是这样会存在一些问题,比如说一个节点包含多个权值(包含多个字符串)的时候就很难进行计算。我最开始是判定已选择的字原创 2017-08-13 14:02:31 · 293 阅读 · 0 评论 -
HDU 4825 字典树
题意中文题,不解释题解很普通的字典树,不过使用上还是有一些技巧的。首先的话,倒着对位存储数组进行赋值。然后存储到字典树以及查询的时候,正着查询,查询的时候尽量向相反的方向查询。这样的话,便可以得到异或值最大的数。注意事项两个需要注意的地方。 第一个地方是存储数位需要倒着存储,这样的话可以保证取得的结果异或值最大。越高位异或值为1越好。 第二个地方是字典树初始化问题,需要注意根节点下标为0,子节点原创 2017-08-05 21:07:21 · 263 阅读 · 0 评论 -
ZOJ 3228 AC自动机
题意给一些字符串,后面跟一个数字。如果0的话,就允许统计层叠的的字符串个数。如果1的话,就只能统计不层叠的字符串个数。要求输出统计个数题解实现起来最简单的方式,也是大家用的最多的方式就是用一个AC自动机,然后在统计的时候,开两个数组分别统计允许层叠的个数和不允许层叠的个数。最后需要输出哪种类型的个数,就直接输出就可以了。代码#include <iostream> #include<cstdio> #原创 2017-08-13 19:31:37 · 200 阅读 · 0 评论 -
HDU 3746 KMP
题意N个字符串,要使字符串为其字串的循环,问最少要添加多少个字符。题解看了题解才意识到这是一道非常水的KMP题,不过对KMP的理解一定要深入。KMP算法的原理就是判断是否存在重复的部分,如果存在重复的部分,则在比对的时候就可以避免比对重复的部分。这个性质也正好可以用来判断循环串的长度。M-第M+1个位置的失配数就是循环串的长度。算出来以后,答案就显而易见了。 关于KMP的模板,感觉刘汝佳的KMP模原创 2017-07-28 17:56:04 · 232 阅读 · 0 评论 -
ZOJ 3494 AC自动机+数位DP
题意有一种BCD编码方案,求A到B范围内的数字的BCD编码有多少个不包含不能包含的字符串。题解数字范围这么大,很明显就能看出来是数位DP。基于AC自动机的数位DP使得数位DP容易了不少,因为AC自动机自带状态转移。在数位DP选取每一位的时候,基于AC自动机状态转移一下,如果转移到不能转移的状态,就直接返回-1。如果转移到合法状态,就继续DFS。唯一需要注意的就是需要大整数的减法,不过随便写写就行了,原创 2017-08-13 21:29:05 · 315 阅读 · 0 评论 -
POJ 1625 AC自动机+大数+字符编码
题意一种语言有N种字符,一句话的长度为M,有P个禁止说的字符串。问能生成多少种可以说的字符串。题解看到这道题,第一眼就能想到是矩阵+AC自动机,于是果断MLE。后来看了题解才意识到这道题的数据范围小,所以DP完全可以解决,也不用构造什么矩阵了。对于不允许的字符串节点,直接continue就可以了。注意事项各种RE,WA,MLE。需要特别注意的是编码问题,编码一定要用“ISO-8859-1”。开始我用原创 2017-08-14 10:28:22 · 294 阅读 · 0 评论 -
UVALive 7902 后缀自动机
题意给N个字符串,找出第一个字符串中最短的一个子串,使得这个子串不在其他所有的字符串中出现。题解对于这样一道题,没有现成的工具可以利用,但是既然涉及到了子串的问题,就可以考虑后缀自动机。后缀自动机可以用来找最长公共子串。对于这道题,我们想要利用后缀自动机,就是需要采取一些措施,使得这个问题转化为最长公共子串的问题。 我们可以把其他字符串拼接成一个字符串,需要注意的是要在中间加上一个分割字符,因为如原创 2017-10-09 19:49:04 · 294 阅读 · 0 评论