得到串a后,拼接出如下串a#rev(a),求出他们的rank和height数组。然后我们对$0\ldots l1-1$扫描,此时需要分两类:

  1. 长度为奇数的回文串
  2. 长度为偶数的回文串

对于情况①,我们要求以$S_i$为中心的最长回文串(设长度为k),我们求$T_{i + 1}$与$T_{l * 2 - i}$的最长公共前缀,容易发现这个最长公共前缀是由$S_i$与$\lfloor \frac{k}{2}\rfloor$长度的回文串的右部分拼接成的,所以此位置情况①的最长回文子串的长度k为$T_i$与$T_{l \times 2 - i}$的最长公共前缀长度×2-1,可用height求

对于情况②,与情况①不同的地方在于$T_i$与$T_{l * 2 - i}$的公共前缀长度正好是以此为中心左侧位置的最长回文子串的长度÷2

我们可以根据中心位置m和最长回文子串的长度来推知起始位置和结束位置,以此为依据输出最长回文子串。

此算法复杂度为$O(n \log n)$

代码见https://github.com/cjsoft/noip/tree/master/after_lnoi/d0517
其中leetlps.cpp是leetcode上的交互版
lps.cpp是普通版