Description
佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物。生日礼物放在一个神奇的箱子中。箱子外边写了一个长为n的字符串s,和m个问题。佳媛姐姐必须正确回答这m个问题,才能打开箱子拿到礼物,升职加薪,出任CEO,嫁给高富帅,走上人生巅峰。每个问题均有a,b,c,d四个参数,问你子串s[a..b]的所有子串和s[c..d]的最长公共前缀的长度的最大值是多少?佳媛姐姐并不擅长做这样的问题,所以她向你求助,你该如何帮助她呢?
Input
输入的第一行有两个正整数n,m,分别表示字符串的长度和询问的个数。接下来一行是一个长为n的字符串。接下来m行,每行有4个数a,b,c,d,表示询问s[a..b]的所有子串和s[c..d]的最长公共前缀的最大值。1<=n,m<=100,000,字符串中仅有小写英文字母,a<=b,c<=d,1<=a,b,c,d<=n
Output
对于每一次询问,输出答案。
分析
s[a..b]的所有子串相当于s[a..b]的一些前缀的后缀。
那么可以先做一遍SA,求出height数组,然后枚举每个i后缀(a≤i≤b),求出它与s[c..d]的LCP,这里可以在它们的rank之间的height求一个最小值得到。时间复杂度 O(n2logn) ,实测只能拿10分。
然而可以考虑二分答案,对于当前的答案mid,我们要在区间[a,b-mid+1]中求是否存在一个后缀,与s[c..d]的LCP大于等于mid。这里就很显然了:首先确定一个区间,包含rank[c]且它们的公共前缀大于等于mid,这里可以用rmq求,然后在这个区间找是否存在开头在[a,b-mid+1]的后缀,用主席树查询。