题意:给你一个字符串,再给你q个询问,每一个询问有l,r,k, 求字符串中下标l到下标r这个子串第k次出现在字符串中的位置,不存在则输出-1.
后缀数组:将所有后缀排序,height数组是比较第i个后缀和第i-1个后缀的最长公共前缀的长度
rmq:求区间的最小/最大数
主席树:求区间第k大的数
首先求出后缀数组(包括height函数),对于每一个询问,我们知道它的开始下标是i,通过后缀数组中的rk[i](表示下标为i的后缀排完序后对应的位置)得到在排好序的所有后缀的位置,现在通过h函数找到公共前缀长度>=r - l + 1的上限和下限,但是如果直接找最坏情况会变成O(n),优化方法是因为h函数的特殊性,懂后缀数组的都知道h[i]>=h[i-1]-1,那么我们先把所有区间的h的最小值用ST表统计出来,然后二分2~rk[l] 和 rk[l + 1] + 1 ~ n找上下限(二分条件是h[mid]>=r - l + 1),找到上下限后,我们现在要求第k个的位置,用主席树预处理下就行了,然后按照主席树的方法查询答案即可。
注意点:上下限的边界情况,如果rk[2]满足,那么下限是1,如果rk[l + 1]不满足,那么上限是rk[l]
/**/
#include
#include
#include
#include
#include
#include
#include