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)\)的。

代码(待更)

posted @ 2019-08-11 10:21  featherZHY  阅读(126)  评论(0编辑  收藏  举报