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 是可以作为答案的,但是我们为什么没有统计上呢,因为我们只统计了后缀而没有统计非后缀的。

于是我们可以将非后缀的变为后缀:将这个将原串反向拼在原串前面,再在原串部分找到所有的回文后缀即可。


后记:

马拉车部分内容不多,因为算法具有较大局限性,可解决问题过少

posted @ 2023-06-21 08:46  Pwtking  阅读(19)  评论(0)    收藏  举报