Manacher演算法總結

2022-04-29 22:21:12 字數 1548 閱讀 1763

之前隊爺講的時候沒聽懂,今天考試考到了,花時間學習一下。

推薦這篇部落格,講的很詳細;

題目:lgoj[p3805]manacher模板

求最長回文子串

o(n)列舉對稱點,再利用回文的性質向兩邊擴充套件,總複雜度o(n2)

這太不優秀了qaq

之前的演算法主要是列舉了重複的子串

栗子:

s="a b a b a a"

i : 1 2 3 4 5 6

>在i=3時會擴充套件到"a bab a"(ps:黑體為當前對稱點,以後不再說明)

>而子串"a b a"在i=2時就已經被訪問過了

如何避免呢?

正如上面所說,我們要避免重複的擴充套件,也就是要利用已有的資訊

這裡我們就要充分利用回文串的性質了

下面的栗子應該可以給你一些啟發:

串s為已經擴充套件完的回文串,長度為len,對稱點為mid(方便起見,假設s為乙個長度為奇數的串)

\(s_1,s_2,s_3...s_,s_,...,s_,s_\)

用陣列\(r_i\)記錄以i為對稱點的最長回文子串半徑

因為s是回文串,所以\(s_i=s_(1<=i<=mid-1)\)

假如我們現在已經知道了\(r_a(a為什麼呢?

因為s串回文,

所以,在s串上位置相對的兩段子串一定是對稱的

於是就可以利用左邊的資訊來更新右邊的資訊了

這基本上就是manacher的思路

盜一波圖:(主要是解釋程式)

①其實左邊的紅格沒啥用

②淺色的格仔為i,j的回文子串

③rl就是r

>在這裡雖然rj很長,但是在大於max_right的部分你並不知道滿不滿足i子串回文(因為在max_right以右並不滿足回文串的性質),所以ri只能到max_right處

上**

1 #include2

#define r register int

3using

namespace

std;

4strings;5

char c[40000007];6

int ls,r[40000007];7

intmain()

8//這樣處理後不用判回文串長度奇偶(c為轉換後的串)

18 r max_right=0,mid=0

;//mid就是圖中的pos

19for(r i=1;i<=len;i++)

2029

}30 r ans=0;31

for(r i=1;i<=len;i++)

3235 cout<1

<

36return0;

37 }

我水平實在是太差了,以上內容不保證正確(qaq)

Manacher演算法總結

所謂回文串,簡單來說就是正著讀和反著讀都是一樣的字串,比如abba,noon等等,乙個字串的最長回文子串即為這個字串的子串中,是回文串的最長的那個。下面介紹manacher演算法的原理與步驟。首先,manacher演算法提供了一種巧妙地辦法,將長度為奇數的回文串和長度為偶數的回文串一起考慮,具體做法...

Manacher演算法總結

演算法總結第三彈 manacher演算法,前面講了兩個字串相演算法 kmp和拓展kmp,這次來還是來總結乙個字串演算法,manacher演算法,我習慣叫他 馬拉車 演算法。相對於前面介紹的兩個 演算法,manacher 演算法的應用範圍要狹窄得多,但是它的思想和拓展kmp 演算法有很多共通支出,所以...

manacher演算法總結

原文 1 len陣列簡介與性質 manacher演算法用乙個輔助陣列len i 表示以字元t i 為中心的最長回文字串的最右字元到t i 的長度,比如以t i 為中心的最長回文字串是t l,r 那麼len i r i 1。對於上面的例子,可以得出len i 陣列為 2 len陣列的計算 首先從左往右...