Manachar(马拉车)
思路
我们设\(rad[i]\)表示以\(i\)为对称点的最长回文串。
设现在\(rad[1..k-1]\)均已算好,以\([1..k-1]\)为对称点的回文串最远匹配到的位置为\(p\),对称点为\(a\),即\(a+rad[a]-1=p\)
现在需要计算\(rad[k]\),假如\(k>=p\),那就暴力更新。
假如\(k<p\),由回文的性质我们知道,\(s[a+1..p]=s[a-1..2*a-p]\)(倒序),那么对于\(k\)位置的\(rad\),可以参照\(2*a-k\)位置的\(rad\)。
显然,若\(k+rad[2*a-k]-1<p\),\(rad[k]=rad[2*a-k]\),证明太水了就不复制了
若\(k+rad[2*a-k]-1>=p\),那由前面的推导可知,此时\(rad[k]>=rad[2*a-k]\),但至于\(rad[k]\)最大能到多少,我们并不知道,所以我们需要暴力匹配,但与从零开始的暴力匹配不同,我们可以从\(rad[k]+1\)开始匹配,然后更新\(a\)和\(p\)。
由于每个点只会被访问一次,所以时间复杂度是\(O(N)\)的。