
ACM-后缀数组
路小白_zZ
这个作者很懒,什么都没留下…
展开
-
poj 1743(后缀数组)
题意:给出一个数字序列,然后问这个序列的变化幅度的不重叠的最长重复子串。 题解:先把这个序列前后相差值计算出来,得到真正要找的最长重复子串的序列。方法是先用DA得到sa数组,然后算出height[i]:名次相邻的两个后缀串的最长公共前缀。用二分枚举最长重复子串的长度x,判断就是只要连续的heighti出现了大于等于x(重复长度)且相差超过x(不重叠),那么这个x就是有效的,二分出满足条件的最大值就原创 2015-10-17 16:46:03 · 528 阅读 · 0 评论 -
lightoj 1314(后缀数组)
题意:给出一个串,问长度为l到r的不同子串的个数。 题解:如果没有给出子串长度范围,个数就是len - sa[i] - height[i]的累加和,给出了左右范围其实也就是多了两个判断,判断len - sa[i]和r的较小值,height[i]和l - 1的较大值,来缩小范围。#include <cstdio>#include <cstring>#include <algorithm>#de原创 2015-11-01 10:32:28 · 515 阅读 · 0 评论 -
SPOJ DISUBSTR(后缀数组)
题意:给出了一个串s,问不相同的子串的个数。 题解:用求后缀数组的函数得到sa[i],height[i],按后缀字典序排好序,相邻的两个串可以得到的不同子串个数是len - sa[i] - height[i],这样把所有的相邻后缀串累加就得到所有不同子串个数。#include <cstdio>#include <cstring>#include <algorithm>#define F(x)原创 2015-10-26 19:19:16 · 451 阅读 · 0 评论 -
poj 3080(后缀数组)
题意:给出n个字符串,输出一个字典序最小的最长公共子串。 题解:把n个串连接起来,先求的后缀数组中height数组,然后二分长度x,根据height[i]判断是否存在一个长度为x的串出现在n个串。#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 800;int原创 2015-10-26 19:22:38 · 836 阅读 · 0 评论 -
SPOJ REPEATS(后缀数组)
题意:给出一个字符串,问重复次数最多的子串的重复次数。 题解:和之前做过的poj3693很像http://blog.youkuaiyun.com/hyczms/article/details/49294095,不过这道题直接输出次数。#include <cstdio>#include <cstring>#include <algorithm>#define F(x) ((x) / 3 + ((x) %原创 2015-10-26 21:32:38 · 471 阅读 · 0 评论 -
poj 3693(后缀数组)
题意:一个由小写字母组成的字符串,问这个字符串内重复次数最多的连续子串,多组解输出字典序最小的。 题解:这里算法合集之《后缀数组——处理字符串的有力工具》例8讲的很明白,先枚举重复子串的长度为L,以s[0],s[L],s[2 * L]…为起点,有两个相邻的长度为L的串重复出现,那么就可以用height求两个后缀的lcp,lcp / L + 1是次数,但不一定是最大次数,还要从首字符向前匹配到不能匹原创 2015-10-21 01:47:19 · 778 阅读 · 0 评论 -
poj 2406(后缀数组)
题意:给出一个串,是由它的一个子串重复k次得到的,问k最大是多少。 题解:从小到大枚举长度i,如果长度i的子串刚好是重复了len/i次,应该满足len % i == 0和rank[0] - rank[i] == 1 和height[rank[0]] == len-i这些条件的,直接判断就可以了,第一次用da倍增超时了(1000000的数据忘了。。。),换成dc3过了。#include <cstdi原创 2015-10-20 19:25:49 · 3147 阅读 · 4 评论 -
poj 2758(后缀数组)
题意:给出一个长度为n的字母组成的序列,然后有两种操作,Q a b 询问以第a个字符为开头的后缀字符串和以第b个字符为开头的后缀字符串的lcp(最长公共前缀)的长度,I a b 表示在第b个字符之前插入字符a。 注意询问时的位置a和b是对应初始串,而比对的后缀串是当前串。 题解:思路想到了,但实现不出来 %>_<%,如果不考虑I操作,先用后缀数组处理出sa和rank,然后得到height相邻名次原创 2015-10-18 21:34:14 · 1184 阅读 · 0 评论 -
poj 3294(后缀数组)
题意:给出n个字符串,求出现次数超过n/2次及以上的最长子串,如果有多组按字典序输出,没有输出?。 题解:多个字符串的处理方式是把所有串连接起来,用没有出现在串中且字典序最大的字符分割,然后二分出一个长度x去判断是否有长度不小于x的公共前缀出现了n/2次以上。需要注意为了判断两个公共前缀不在一个串中,要把每个串的起始位置记录到sum数组,然后连续的height[i]>=x情况下,如果sa[i]所在原创 2015-10-18 00:57:06 · 659 阅读 · 0 评论 -
poj 3261(后缀数组)
题意:给出一个长度为n的数字序列,问可重叠的最长重复子串出现至少K次的长度。 题解:二分出长度x,判断连续height[i] >= x的情况如果出现K-1次就可以判断这个长度是成立的。#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 20005;int wa[N原创 2015-10-17 19:40:25 · 451 阅读 · 0 评论 -
poj 2774(后缀数组)
题意:每次给出两个串,问两个串的最长公共子串的长度。 题解:后缀数组算法合集之《后缀数组——处理字符串的有力工具》这里讲解的很好,把两个串连接起来,然后求这个串的后缀数组,和对应的height[i]的最大值,但主要要满足sa[i]和sa[i-1]在不同的串中。#include <cstdio>#include <cstring>#include <algorithm>using namesp原创 2015-10-17 13:49:26 · 556 阅读 · 0 评论 -
lightoj 1428(后缀数组)
题意:给出字符串A和字符串B,问A的多少个不同子串内不含B。题解:这个是看题解的,多加了一个rmax数组,rmax[i]表示A串的第i个位置(从0开始)最多向后延伸多少个字符的子串可以不包含B,相当于给出A的每个后缀的右范围,rmax数组的确定可以先把A和B串用一个很大的字符间隔并连接,然后得到height[i],sa[i],rank[i],在按字典序排好的后缀串中,从rank[lenA+1] +原创 2015-11-01 10:44:09 · 425 阅读 · 0 评论