manacher

给定一个字符串,求出以每个位置为中心的最长回文子串。


流程

  • \(mxr\) 为当前所有回文串的最大的右边界,\(mid\) 为对应的中点

  • 为了防止中点在两个位置中间,将原串的每两个字符间和开头结尾都塞一个相同的无关字符

  • \(i\leq mxr\),令 \(f_i=\min(f_{2mid-i,mxr-i+1})\)

  • 暴力扩展 \(f_i\)

  • 更新 \(mxr\)\(mid\)


正确性

对于一个回文字串来说,一对下标以 \(mid\) 对称的区间一定完全相同。所以在 \(mid\) 左边的一个回文区间对应的右边的一段区间一定也是回文区间。

所以 \(i\) 在这个回文字串内的答案一定不小于它的对应点 \(2mid-i\) 在这个回文子串内的答案。


复杂度

分析暴力扩展部分的复杂度即可。。

  • 若以 \(i\) 为中心的最长回文串的右端点 \(R\) 小于 \(mxr\),则 \(f_i=f_{2mid-i}\)

  • 否则会提供 \(R-mxr\) 的复杂度,并且令 \(mxr=R\)

然后发现复杂度就是把 \(mxr\) 一直往右边挪的次数。

复杂度 \(O(len)\)

posted @ 2021-06-25 09:17  oisdoaiu  阅读(35)  评论(0编辑  收藏  举报