Tjoi2016&Heoi2016 字符串
问题描述
佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物。生日礼物放在一个神奇的箱子中。箱子外边写了一个长为n的字符串s,和m个问题。佳媛姐姐必须正确回答这m个问题,才能打开箱子拿到礼物,升职加薪,出任CEO,嫁给高富帅,走上人生巅峰。每个问题均有a,b,c,d四个参数,问你子串s[a..b]的所有子串和s[c..d]的最长公共前缀的长度的最大值是多少?佳媛姐姐并不擅长做这样的问题,所以她向你求助,你该如何帮助她呢?
输入格式
输入的第一行有两个正整数n,m,分别表示字符串的长度和询问的个数。接下来一行是一个长为n的字符串。接下来m行,每行有4个数a,b,c,d,表示询问s[a..b]的所有子串和s[c..d]的最长公共前缀的最大值。
输出格式
对于每一次询问,输出答案。
样例输入
5 5
aaaaa
1 1 1 5
1 5 1 1
2 3 2 3
2 4 2 3
2 3 2 4
样例输出
1
1
2
2
2
提示
1<=n,m<=100,000,字符串中仅有小写英文字母,a<=b,c<=d,1<=a,b,c,d<=n
首先,后缀自动机上处理公共前缀问题都是将原串倒过来建立后缀自动机。
倒过来处理之后,$a’=n-b+1,b’=n-a+1,c’=n-d+1,d’=n-c+1$问题转换为询问s’[a’…b’]的所有子串与s’[c’…d’]的最长公共后缀的最大值。
直接找并不好找,考虑二分答案,将最优化问题转为判定性问题。
假设答案是$mid$,问题就转换为了判断s’[d’-mid+1,d’]是否为s’[a’…b’]的子串。那么只需要判断s’[d’-mid+1,d’]的right集合中是否含有[a’+mid-1,b’]中的位置即可。
找到s’[d’-mid+1,d’]的对应位置用倍增,维护right集合采用线段树合并。时间复杂度$O(nlog^2n)$
1 |
|