hdu 6704 后缀数组+主席树+RMQ
给一个长为n的字符串,m次询问,每次求子串[l,r]第k次出现的起点位置 做法: 数据量很大,输入的字符串/询问总量可以达到1e5*5,必须尽量实现单次$O(logn)$的查询和至多$O(nlogn)$的预处理 1.子串[l,r]一定是某个后缀的前缀,而"后缀的前缀的重复出现"这个问题可以很容易想到后缀数组的height 2.考虑重复出现,显然一个后缀的长为r-l+1的前缀的出现位置即为height数组上一段连续的大于等于r-l+1的区间 3.得到这个区间后,就变成了一个在sa数组上求区间第k小的问题了 那么做法就是: 预处理: 1.预处理height数组 2.预处理height数组区间min的st表 3.预处理支持查询sa数组上的区间kth的 一棵可持久化线段树 处理询问: 1.我们从后缀数组的rk[l],直接锁定一个合法的起始位置, 2.然后利用st表快速二分出一个合法的连续区间,满足min>=r-l+1, 3.在可持久化线段树上查询这个区间的kth小 总复杂度:$O((m+n)logn)$ (说起来挺复杂,但是也就130行) #include<bits/stdc++.h> #define ll long long #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b)