Manacher
算法原理:和ex看毛片kmp原理近乎相同,都是用前面已求出的来更新当前值
一些性质:
以下将已求出的以每个字符(字符在已经处理过的文本串上) \(s_i\) 为中心的最长回文半径称为 \(d[i]\)。
当 \(s_i =\) # 时,则 \(d[i]\) 代表以 \(s_{i+1}\) 和 \(s_{i-1}\) 中间位置为中心的回文串的半径(偶回文串)。
否则则代表以当前自古为中心的奇回文串。
做题笔记:
(徒手爆切的一题还是挺爽的
首先很显然的一种方法是直接以 \(s\) 当作 \(s*\) 回文串的左半部分再将右半部分拼上,但这显然在一些情况下是没必要的。
观察下面的例子:
abbb
如果想我们刚才一样去拼的话得到的就是:
abbbbbba
但是答案显然是:
abbba
观察到了什么?
因为其中存在回文串 bbb,我们可以利用他的回文性质来简短 \(s*\) 长度。
但是我们又发现只有回文串在 \(s\) 的末尾,即 \(s\) 的后缀,才能帮我们减短长度:比如当 \(s\) 为 abbbc 时, bbb 就起不到作用了。
所以为了新的 \(s*\) 要最短,我们只需要找出 \(s\) 的最长回文后缀,再将 \(s\) 的非最长回文后缀部分反着拼到前面即可。
又是徒手切的,爽
和上一题有异曲同工之妙!
我们只需要找到所有的回文后缀即可。
但很显然这样你直接就 WA。
比如样例的 qwqwq, qw 是可以作为答案的,但是我们为什么没有统计上呢,因为我们只统计了后缀而没有统计非后缀的。
于是我们可以将非后缀的变为后缀:将这个将原串反向拼在原串前面,再在原串部分找到所有的回文后缀即可。
后记:
马拉车部分内容不多,因为算法具有较大局限性,可解决问题过少

浙公网安备 33010602011771号