Manacher算法学习笔记

1.介绍
Manacher算法可以在线性时间内处理出关于一个字符串的所有子回文串的信息
2.表示方式
一个回文串可以由两个东西唯一确定:中心位置和长度
Manacher算法维护两个数组\(d1_i\)\(d2_i\),分别表示以\(i\)为中心的最长回文子串的长度的一半(下取整)
比如\(d1_i = k\),则以\(i\)为中心,长度为\(1 \sim 2k-1\)的串都是回文串
3.求法
\(d1_i\)为例
我们维护右端点最靠右的子回文串\([l,r]\),即\(s[l\sim r]\)
对于每个i
\(i > r\),那么直接枚举回文串的右端点,暴力判断,到不是回文串时停止
\(i \leq r\),令\(j=l+r-i\),由于\([l,r]\)为回文串,那么这时显然有\(d1_i = d1_j\)
为什么?因为\(i\)\(j\)处在一个回文串对称的位置
但是有一个问题:当\(d1_i + i - 1 \geq r\)时,超出\(r\)的部分无法保证对称
这时我们仿照\(i > r\)时的方法暴力跳即可
4.时间复杂度分析
可以发现,时间复杂度的瓶颈在于暴力判断的过程
注意到暴力判断只有在当前需要判断的位置\(>r\)时才会被执行
所以暴力判断每执行一次,\(r\)都会增长\(1\)
\(r \leq n\),所以时间复杂度为\(O(n)\)
5.参考资料
OI-wiki

posted @ 2021-02-27 17:32  ctt2006  阅读(40)  评论(0)    收藏  举报