Manacher回文串算法
Manacher
: $O(n)$的寻找回文串。
P3805【模板】manacher 算法
题目描述
给出一个只由小写英文字符 $\texttt a,\texttt b,\texttt c,\ldots\texttt y,\texttt z$ 组成的字符串 $S$ ,求 $S$ 中最长回文串的长度 。
字符串长度为 $n$。
输入格式
一行小写英文字符 $\texttt a,\texttt b,\texttt c,\cdots,\texttt y,\texttt z$ 组成的字符串 $S$。$1\le n\le 1.1\times 10^7$。
输出格式
一个整数表示答案。
样例 #1
样例输入 #1
1 |
|
样例输出 #1
1 |
|
Idea
预处理
在原字符串的每个字符用一个字符集中不存在的字符隔开。
比如,对于一个由a
到z
的字符组成的串 aabbbaa
-> |a|a|b|b|b|a|b|
这样做是为了使每个回文串都能找到对称中心。
对于一个长度为偶数的字符串 aaaa
他的对称中心在2和3之间。如果插入字符,|a|a|a|a|
,第5个字符就是他的中心。
计算
定义p[i]
为每个字符的回文半径。同时记录一个mid,一个r,分别代表已经确定的右侧最靠右的回文串的对称中心和右边界。
对于第 i
个字符:
- 如果
i <= r
,p[i] = min(p[m * 2 - i], r - i + 1)
p[m * 2 - i]
是与i
关于点m
对称的点。如果以这点为中心的最长回文串在[m-r, m]
范围内,p[i]
显然也会具有这样一个回文串。如果以这点为中心的最长回文串超出了
[m - r, m]
范围,至少在[m - r, m]
范围内的回文串是有效的,可以被传递给p[i]
。
- 否则
p[i] = 1
。
随后暴力计算p[i]
。
该字符串中的最长字串为:max(p[i]) - 1
。p[i]
中计入了额外的分隔符,数目与回文中心的另一端等长,也就相当于回文串的长度。
Code
1 |
|
Manacher回文串算法
https://a48zhang.github.io/2023/07/12/Manacher回文串算法/