學習筆記 manacher演算法

2022-09-21 05:27:06 字數 2383 閱讀 8692

一.關於manacher

manacher演算法用於求解乙個字串的回文子串半徑長度。

它可以線性地求解對於字串中的每乙個字元,以它本身為中心的最長回文串的半徑。

而且這個回文串的每乙個以這個字元為中心的子串都是回文串。

這個演算法的時間複雜度為o(n)。

二.回文子串長度的奇偶性帶來的問題。

當乙個回文串長度是奇數的時候,它必然有乙個回文中心,回文中心兩側的部分是相互對稱的。

那麼 當乙個回文串長度是偶數的時候,它沒有回文中心……,那麼該怎麼辦呢?

我們考慮人為構造乙個回文中心。

構造的方法就是在原字串的每兩個字元中間插入相同的乙個原串中必定沒有的字元,這樣我們就可以發現:

當原串的回文子串長度為奇數,它的回文中心是原串中的字元。

當原串的回文子串長度為偶數,它的回文中心是我們新插入的字元。

好了。完美解決了這個問題。

三.manacher演算法流程。

我們再次確認一下,manacher演算法用於求解對於字串中的每乙個字元,以它本身為中心的最長回文串的半徑。

我們把字串中的每乙個字元,以它本身為中心的最長回文串的半徑記入乙個陣列叫p。

時間複雜度o(n)要完成這個事,就必須通過遞推的方式求解p陣列。

1.回文串的對稱性

上文我們提到回文串具有對稱性。

我們假設現在有乙個字串:s[11]:abababababa

我們顯然可以看出這個字串自己就是乙個回文串,這個回文串的回文中心是s[5](下標從0開始)。

觀察s[2]為中心的回文串,是不是和s[8]為中心的相等長度的回文串完全相等?

2.兩個重要的引數:maxr,mid.

所以我們可以通過p[2]推到p[8],但這些都有個前提條件,即p[5]≥4。

因為前提是 以乙個大回文串的回文中心為對稱點的兩個子回文串中心,它們所能拓展出的最長回文串的半徑一定是相同的。

所以我們要維護大回文串的右端點maxr和中心mid來確保轉移。

但這樣的轉移不一定使得p是最長回文半徑,所以我們進行暴力拓展就行了。

整體複雜度o(n)。

三.**

注意在向外拓展的過程中 字串的左側和右側要賦上不同的符號,否則可能會tle。

洛谷【模板】manacher演算法:

1 #include2

using

namespace

std;

3long

long n,ans,p[22000002];4

char c[11000001],s[22000002];5

intmain()

613 s[0]='+'

;14 s[2*n+1]='!'

;15 s[2*n+2]='-'

;16long

long maxr=0,mid=0;17

for(int i=1;i<=n*2;i++)

1827}28

for(int i=1;i<=n*2;i++)

2932 printf("

%lld

",ans);

33 }

view code

四.相關習題

1.洛谷 p1659

本題相對比較簡單。因為題中規定了所有的回文串都為奇數,所以都不用插板了。

因此我們可以暴力跑manacher,然後倒著列舉長度,用快速冪統計答案就好了。

1 #include2

#define mod 19930726

3using

namespace

std;

4long

long n,k,cnt[1000001],p[1000001],ans=1;5

char s[1000001];6

long

long quickpow(long

long a,long

longb)7

15 a=a*a%mod;

16 b>>=1;17

}18return res%mod;19}

20int

main()

2135

if(i+p[i]>maxr)

3640}41

for(int i=1;i<=n;i++)

4245

int sum=0;46

for(int i=n;i>=1;i--)

4755

else

5660}61

if(k>0) ans=-1

; 62 printf("

%lld

",(ans+mod)%mod);

63return0;

64 }

view code

學習筆記 Manacher演算法

manacher 中文 馬拉車 演算法,即求解給定字串中最長回文子串長度的演算法。洛谷p3805 給出乙個長度為 n 的只由小寫英文本元 mathtt 組成的字串 s 求 s 中最長回文串的長度 一般情況下回文串有奇偶分類。為了避免分類,我們在字串中間新增特殊字元 不妨用 在串的首尾加上不同的特殊字...

Manacher演算法 學習筆記

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

Manacher演算法學習筆記

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