后缀数组
qq_45778406
这个作者很懒,什么都没留下…
展开
-
Mike and Friends(后缀数组 + 线段树)
题意:给你n个字符串,和x, y, k, 问你从第x个字符串到第y个字符串中一共有多少个这些字符串的子串和第k个字符串相等。 思路:参考题解, 也可以等价转换为求和第k个字符串相等的子串有多少,根据后缀数组定义我们可以在我们可以求所有和s[k]相等的子串的数量,定义母串为所有字符串拼起的字符串(因为sa[i]是按照字典序排序的结果, 我们只需以s[k]母串中的位置为中心P,分别求出LCP(L,P)==len(s[k]),LCP(P,R)==len(s[k])LCP(L, P) == len(s[k]), L原创 2021-05-10 21:21:56 · 227 阅读 · 0 评论 -
Life Forms POJ - 3294(后缀数祖 + 二分 + 分组)
POJ - 3294 题意:给你n个字符串, 让你找到至少在n/2个字符串中出现的最长的公共子串(有多个按字典序全部输出) 思路:和前几题类似, 先把各个串连接起来, 用不相同的字符(最好换成数字, 不然容易出bug), 然后求一遍后缀数组即可。然后二分公共子串的长度, 对于二分的每一个值check一下, 在check中按照是否连续的大于mid来分组, 对于每一组内我们只需要判断来自不同的串的数量是否大于n / 2即可 细节见于代码 #include <iostream> #include &l原创 2021-04-17 14:59:25 · 227 阅读 · 0 评论 -
Common Substrings (求有多少个长度大于K的公共子串。)
链接 POJ - 3415 题意:给出两个字符串s1、s2和一个整数K,求有多少个长度大于K的公共子串。 思路: 参考题解: 现将s = s1 + ‘$’ + s2;(做出后缀数组) 有后缀数组height的特性可知可将排名1~n的后缀串通过是否公共子串大于k来分组 我们只需求出每一组中的长度大于K的公共子串, 在相加即可得到答案; 对于每一组 朴素方法: 枚举组内的每一个s1中的后缀再枚举在该组中的每一个s2中的后缀, 答案为(height[i] - k + 1) * (height[j] - k +原创 2021-04-16 19:09:52 · 223 阅读 · 0 评论 -
Maximum repetition substring(重复次数最多的连续重复子串)
后缀数组模板题 参考论文 先穷举长度 L,然后求长度为 L 的子串最多能连续出现几次。首先连续出现 1 次是肯定可以的,所以这里只考虑至少 2 次的情况。假设在原字符串中连续出 现 2 次,记这个子字符串为 S,那么 S 肯定包括了字符r[0],r[L],r[L∗2],r[L∗3],……r[0], r[L], r[L*2], r[L*3], ……r[0],r[L],r[L∗2],r[L∗3],……中的某相邻的两个。所以只须看字符r[L∗i]和r[L∗(i+1)]r[L*i]和 r[L*(i+1)]r[L∗i原创 2021-04-14 21:15:43 · 532 阅读 · 0 评论 -
Musical Theme POJ - 1743(最长不重复字串,二分加后缀数组)
题目大意 给出一串数字(每个数字范围1…88),问是否存在两个长度相等的不重叠子串,两串每两个同位数字的差值为定制。长度小于5则输出0,否则输出最大长度。 思路: 一个巧妙的处理差分, 差分后每个差分的值,然后直接套后缀数组即可,但后缀数组无法直接求解, 后缀数组的height数组能求排名相邻的两个字符串的公共前缀, 我们不仅需要两个字符串之间的公共前缀大于4,还需要字符串之间的距离大于5, 显然可以按照是否大于5将height分组,答案就在某个组内 /* 题意 给出一串数字(每个数字范围1...88),问原创 2021-04-10 16:54:41 · 150 阅读 · 0 评论 -
后缀数组模板RMQ
Link #include <bits/stdc++.h> #include <cstring> #include <algorithm> using namespace std; const int N = 1000010; int n, m; char s[N]; int sa[N], x[N], y[N], c[N], rk[N], height[N]; //sa[i]排名为i的后缀是哪一个 void get_sa() { for(int i = 1; i &原创 2021-03-31 19:18:52 · 146 阅读 · 0 评论