恩,我们进行一些瞎YY,首先询问s[a~b]的所有子串与S[c~d]的最长LCP其实相当于询问s[a~b]的所有后缀与s[c~d]的最长LCP与这个子串的长度还有c~d的长度取min
进一步转化设suf[i]表示S的从第i个字符开始的后缀,则其实相当于询问这个
可以把d-c+1提到外面,就变成
这样只需要考虑左面的,考虑若答案为l(l<=d-c+1),则作为答案的后缀不可能取在i>b-l+1的位置,而在a<=i<=b-l+1的范围内,只要LCP(suf[i],suf[c])>=l,那么s[i~b]就是一个与s[c~d]有长度为l的LCP的子串
这样我们可以在<=d-c+1的范围内二分答案,每次只要判断a<=i<=b-mid+1的范围内是否存在LCP(suf[i],suf[c])>=mid即可,这个判断可以先建一颗后缀树,在后缀树上倍增找到suf[c]的最浅的长度>=mid的祖先,然后判断这个祖先的子树内是否有a<=i<=b-mid+1的后缀即可,这个可以用主席树
复杂度 O(m log^2 n)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include