后缀数组
meopass
即使摸爬滚打,满身泥泞,我也要前进
展开
-
HDU 6153 A Secret KMP
简略题意:给出两个长度为1e6的S,T串,问T串的每个后缀在S中作为子串出现的次数记为Si, 长度为Li,问∑len−1i=0Si∗Ti\sum_{i=0}^{len-1} Si*Ti的答案。首先将两串都反转,从而变成前缀的处理关系。 对串2建立fail数组,用串1去进行匹配,再在fail树上累加一下前缀和即可。 复杂度是O(n)的。#include <bits/stdc++.h>using n原创 2017-08-20 08:36:38 · 301 阅读 · 0 评论 -
POJ 3294 后缀数组
简略题意:求出现在不少于k个字符串的最长子串。先将nn个字符串用不同的字符连接起来,二分答案tt,用tt分组之后看同一组的是否出现在不少于kk个原串中。 麻烦的是要输出答案,因此还是要仔细做。#include <iostream> #include <cstring> #include <map> #include <cstdio> #include <vector> #include <algo原创 2017-09-12 17:40:16 · 275 阅读 · 0 评论 -
POJ 3415 后缀数组 + 单调栈
简略题意:求两个串长度不小于k的公共子串的个数。 我喜欢这题! 首先按height分组,随后对于每个A后缀,看之前出现的B后缀与其的LCP,若其长度为xx,则对答案的贡献为x−k+1x-k+1。暴力查找n2n^2, 其实B后缀的排名越接近当前A后缀,两者的LCP越高 想一想,为什么, 因此维护一个单调栈,以及栈内元素贡献总和。显然从栈底到栈顶元素逐渐增大。对A统计完答案之后再对B统计一次即可。#原创 2017-09-12 17:36:21 · 315 阅读 · 0 评论 -
POJ 2774 后缀数组
简略题意:求两个字符串的最长公共子串其实解法和51NOD 1089 最长回文子串一样…#include <iostream> #include <cstring> #include <map> #include <cstdio> #include <vector> #include <algorithm> using namespace std;const int N = 2e5+10;int n;原创 2017-09-12 17:29:38 · 285 阅读 · 0 评论 -
POJ 3693 后缀数组
简略题意:求一个字符串中的重复次数最多的连续重复子串。 如(“dababab”,答案为3),要求输出字典序最小的那个。论文里已经说了大致解法了,还需要补充一些。 对于向后扩展,可以用LCP,而对于向前扩展,暴力扩展即可,按照我们枚举的方式,显然可以证明向前扩展不会超过L。现在,我们得到了最大重复次数,还需要得到字典序最小的串。 其实我卡在这里了,我把所有能组成的串全部提取出来,用strin原创 2017-09-12 17:25:52 · 268 阅读 · 0 评论 -
POJ 2406 后缀数组 或 KMP
简略题意:求解一个连续重复串的最大重复次数。连续重复串:如果一个字符串L由字符串S重复R次得到,那么L是一个连续重复串,R是这个字符串的重复次数。KMP的解法和后缀数组异曲同工。 不过为了练习后缀数组,这里只说后缀数组的解法。吐槽一下: 虽然是KMP的水题,不过用后缀数组写起来还是很烦的。 1. 卡时间,倍增的后缀数组过不去。 2. 卡空间,因为串很长,所以不能用一般O(nlogn)O(nl原创 2017-09-12 17:18:11 · 385 阅读 · 0 评论 -
51NOD 1089 后缀数组 或 manacher
简略题意:求解最长回文子串。经典问题,为了练习后缀数组再写一遍吧。 将原串和原串的反转串用没用过的字符拼接起来,发现原问题等价于求最大height[i], 且sa[i-1]和sa[i]分别在原串和反转串中。 复杂度O(nlogn) 嘿嘿嘿,刚从uoj搞了个sais的板子 复杂度O(n)。#include <iostream> #include <cstring> #include <map>原创 2017-09-12 17:10:16 · 251 阅读 · 0 评论 -
SPOJ 694 后缀数组
简略题意:求不相同的子串的个数。求出sa之后,会发现每按名次加入一个后缀,会产生n-sa[i]个新的子串,其中有height[i]个之前已经出现过。答案为n-sa[i]+height[i]。#include <iostream> #include <cstring> #include <map> #include <cstdio> #include <vector> #include <algori原创 2017-09-12 17:04:01 · 300 阅读 · 0 评论 -
POJ 3261 后缀数组
简略题意:求可重叠的至少出现t次的最长重复子串。 (数值好像很大啊,我们来离散化一下吧) 先二分长度k,随后按照height不小于k分组,若存在一组的个数不小于t即可满足条件。#include <iostream> #include <cstring> #include <map> #include <cstdio> #include <vector> #include <algorithm> u原创 2017-09-12 17:00:28 · 270 阅读 · 0 评论 -
POJ 1743 后缀数组
简略题意:求不可重叠的最长重复子串。这题有以下坑点。 1. 给出的n个数不是我们要处理的串,差方之后的串才是。 2. 不可重叠指的是原数组之间不可重叠,例如”1 2 3 4 5 6 7 8 9”的答案为0,而不是5。注意之后,我们只需要二分答案k,按height不小于k分组,存在一组最大最小位置差大于k即可(不能为k,理由见坑点2)。复杂度O(nlogn)。#include <iostream>原创 2017-09-12 16:53:57 · 196 阅读 · 0 评论 -
HDU6194 后缀数组
简略题意:问在一个字符串中出现次数等于k次的子串有多少种。考虑按kk对height进行分组,则当前分组对答案的贡献为: 组内所有元素的的max(0, LCP - max(组内第一个元素与之前元素的LCP, 组内最后一个元素与之后元素的LCP))。 举例来看就是: k=2k = 2 *1. abcabc *2. abcabcabcabc *3. abcabcabcabcabcabc *4原创 2017-09-13 11:54:10 · 946 阅读 · 0 评论 -
POJ 1226 后缀数组 或 KMP 或 暴力
简略题意:出现或反转后出现在每个字符串中的最长字符串。先将每个串和自己的反转串连接起来,随后将这若干个串连接起来。二分答案,判定就分组看是否有一组后缀在所有原串或者原串的反转串中出现。#include <iostream> #include <cstring> #include <map> #include <cstdio> #include <vector> #include <algorithm原创 2017-09-13 10:00:22 · 267 阅读 · 0 评论 -
SPOJ 220 后缀数组
简略题意:每个字符串中至少出现两次,且不重叠的最长子串先将nn个字符串连接起来,二分答案tt,用tt分组之后看同一组的是否出现在所有串中至少两次,且在每个原串中的最大最小sa[i]−sa[j]>=ksa[i]-sa[j]>=k。其实只要同时存在最大最小位置,即出现了至少两次。#include <iostream> #include <cstring> #include <map> #include原创 2017-09-12 17:43:54 · 241 阅读 · 0 评论