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