學習筆記 Manacher演算法

2022-08-14 22:12:13 字數 1520 閱讀 2668

manacher(中文:馬拉車)演算法,即求解給定字串中最長回文子串長度的演算法。

洛谷p3805

給出乙個長度為 \(n\) 的只由小寫英文本元\(\mathtt\) 組成的字串 \(s\) ,求 \(s\) 中最長回文串的長度 。

一般情況下回文串有奇偶分類。

為了避免分類,我們在字串中間新增特殊字元(不妨用 『#』),在串的首尾加上不同的特殊字元(不妨用 『&』 和 『@』)。

例:串 s = baabcoc 轉化為串 s_new = b#a#a#b#c#o#c#@

這樣就將字串中原有的回文串都轉化成了奇回文串

我們構造乙個輔助陣列 \(p\) ,設 \(p[i]\) 表示以 \(i\) 為中心的最長回文子串(新串)的半徑,則以 \(i\) 為中心的最長回文子串(原串)的長度為 \(p[i]-1\)

例:

接下來考慮 \(p[i]\) 的更新。

設變數 \(id\),\(mr\),其中 \(mr\) 表示以 \(id\) 為中心的最長回文子串的右端位置的下乙個位置,即 \(mr=id+p[id]\)

那麼就有:

if(i\(2 \times id-i\)  表示 \(i\) 關於 \(id\) 對稱後的位置,而 \(mr-i\) 表示從 \(i\) 到回文子串右端點的長度。

設 \(j=2 \times id-i\)

如果 \(p[j],則根據** \(p[i]=p[j]\),如果 \(p[i]\) 還能更大,那麼根據對稱,\(p[j]\) 也應該更大(由於 \(p[j],所以 \(p[j]\) 至少可能大1),這就與 \(p[j]\) 已求最大值矛盾。

如果 \(p[j]>mr-i\),則根據** \(p[i]=mr-i\),如果 \(p[i]\) 還能更大,那麼根據對稱,\(p[id]\) 也會更大(從關於 \(i\)、\(j\)、\(id\) 對稱三個方面可推導),這就與 \(p[id]\) 已求最大值矛盾。

其他情況就通過暴力求解。

#include#include#includeusing namespace std;

const int maxn=11000010;

int len,p[2*maxn],j=2;

char n[maxn],a[2*maxn];

int main(){

cin>>n;

len=strlen(n);

a[1]='$';a[2]='#';

for(int i=0;i從**中可以看出 \(mr\) 只會不斷擴充套件,且在 \(mr\) 以內不會進行暴力擴充套件(在前面計算 \(p[id]\) 時都考慮過了),所以均攤複雜度是 \(o(n)\)。

學習筆記 manacher演算法

一.關於manacher manacher演算法用於求解乙個字串的回文子串半徑長度。它可以線性地求解對於字串中的每乙個字元,以它本身為中心的最長回文串的半徑。而且這個回文串的每乙個以這個字元為中心的子串都是回文串。這個演算法的時間複雜度為o n 二.回文子串長度的奇偶性帶來的問題。當乙個回文串長度是...

Manacher演算法 學習筆記

首先,強烈安利一篇文章,這篇文章對於 manacher 的講解本人感覺非常到位。傳送門相信大家都知道的乙個方法 列舉字串的每乙個位置作為回文子串的對稱中心,同時向左向右擴充套件,判斷是否相等,然後每次儲存之前求取的最大回文子串長度,時間複雜度為 o n 2 在列舉時,還需要考慮對奇數回文串和偶數回文...

Manacher演算法學習筆記

manacher演算法是乙個求乙個字串中最長回文連續子串行的演算法 p3805 模板 manacher 演算法 description 求最長回文子串的長度 solution 我們先引入乙個 o n 2 的做法,列舉每個字元為回文串的中心,嘗試向兩邊擴充套件,用擴充套件的最大長度更新答案。為了下文描...