这大概是个 PAM 题,而我们用 Manacher + SA 做。那么如何取代 PAM 这么强大的功能呢?这里有一条在回文子串题中的强大定理(是 yxh 教我的,后来我又到度娘上证实了一下):一个串的本质不同回文子串个数为 (mathrm O(n))。证明及分布:考虑归纳,假设 (a_{1sim i-1}) 满足,那么现在考虑以 (i) 结尾的回文子串们。那么根据回文的性质,非最长者一定包含在最长者中而被对称到最长者开头,此时结尾不可能是 (i),根据假设一定被在 (a_{1sim i-1}) 中算过。于是只需要算最长者即可(不过不保证最长者没有被重复算)。
那么大部分关于求整串的所有回文子串的信息的题,都可以用这个结论秒掉(除了洛谷上 PAM 模板题,强制在线加入字符就比较恶心)。例如本题,考虑如何求出每个点结尾的最长回文子串,首先先隔一个打一个分隔符,然后 Manacher,每个中心显然会更新某个区间的值。那就差分一波,set
扫一遍即可得到以每个点结尾的最长回文子串的中心。
然后因为这题是要求所有回文子串的某个函数值的 max,所以不用去重。直接考虑对每个回文子串求出现次数。这大概是 SA 的经典用法之一,不过我好像以前从来没用到过?设这个子串为 ([l,r]),那么 ([l',l'+r-l]) 与之相等当且仅当 (mathrm{LCP}(l,l')geq r-l+1)。那么后缀排序之后,满足条件的 (l') 显然是一个区间,我们只需要找出最靠近某一个位置的满足 (hi_x<c) 的两个 (x) 即可。这个没像区间前驱后继这么毒瘤,这个只需要线段树上二分即可,就每个节点记录最小 (hi) 值即可。
Manacher + SA + 线段树二分板子三合一,轻微卡常,不全开 ll
(如果全开 ll
还会 MLE。。。) + O2 就 A 掉了。