Manacher 馬拉車演算法

2022-05-22 18:21:13 字數 2273 閱讀 3874

部分資料來自:

給定乙個字串

求最長回文字元子串,注意是最長子串,不是最長子序列!!

如:s="abbacbca",最長回文子串為 "acbca",長度為5;

如果用暴力的演算法,列舉對稱軸,向兩邊延伸,複雜度高達on2

回文串 分為 奇回文串(如"acbca") 和 偶回文串(如 "abba")

那麼演算法為了解決奇偶問題

它選擇將所有空隙填上無關字元'#'

使得上面的兩個串變成"#a#c#b#c#a#" 和 "#a#b#b#a#"

這樣他們的長度恆定是奇數,便於下面的處理

還有一點,為了避免更新越界,我們在字串的前增加乙個特殊字元,比如說『$』,所以演算法中字串是從1開始的。

用來儲存以i為中心的最長字串的左右半徑(包括自己)

如下面:

len陣列有乙個性質,那就是len[i]-1就是該回文子串在原字串s中的長度

從左往右依次計算len[i]

顯然當計算len[i]時,lenj已經計算完畢。

設p為之前計算中最長回文子串的右端點的最大值,並且設取得這個最大值的位置為po,

我們現在研究i,取i相對於po的對稱位置,設為j,分兩種情況:

第一種情況:i<=p####

1)如果len[j]

那麼說明以j為中心的回文串一定在以po為中心的回文串的內部,且j和i關於位置po對稱,由回文串的定義可知,乙個回文串反過來還是乙個回文串,所以以i為中心的回文串的長度至少和以j為中心的回文串一樣,即len[i]>=len[j]。因為len[j]由對稱性可知len[i]=len[j]。

2)如果len[j]=

由對稱性,說明以i為中心的回文串可能會延伸到p之外,而大於p的部分我們還沒有進行匹配,所以要從p+1位置開始乙個乙個進行匹配,直到發生失配,從而更新p和對應的po以及len[i]。

第二種情況:i>p####

如果i比p還要大,說明對於中點為i的回文串還一點都沒有匹配,這個時候,就只能老老實實地乙個乙個匹配了,匹配完成後要更新p的位置和對應的p、o以及len[i]。

上面的情況列舉的比較詳細,但是實際寫**,可以把第一種的第2類分別拆成兩部分,合併另為兩種情況裡面去,這要可以使得**量和可讀性大大提公升

#include#include#includeusing namespace std;

#define maxn 10000005

typedef long long ll;

int main()

cout有一說一,打這場晚上我突然腦袋一熱來看馬拉車,結果當晚cf直接就來了...

題意:給定乙個字串,現在讓你取它的乙個字首和字尾,拼起來使得是回文串,求最長的方案,並輸出之,有多組資料

思路:這個就是馬拉車的經典使用了

首先前後只要是一樣的就能拿出來

接下來的問題無非就是選取剩下這個子串中的最長字首或者最長字尾,使得它是回文串

這個就是manacher的功能了

字尾逆序就是字首了,而你更新最大回文子串要保證他是字首,無非就要保證radius要等於當前下標即可

值得一提的是,因為多組資料,然後沒做清空陣列處理,很容易導致越界訪問,所以要格外注意

ac:#include#include#include#include#includeusing namespace std;

#define inf 1e10+5

#define maxn 1000005

typedef long long ll;

char a[maxn<<1];

int radius[maxn<<1];

string check(string aa,bool re)

aa=s.substr(0,ans-1);

if(!re)reverse(aa.begin(),aa.end());

return aa;

}void solve()

return 0;

}

Manacher 馬拉車演算法

給定乙個字串,求出其的最長回文子串 乙個將時間複雜度優化到o n 的演算法 暴力演算法,但不是純暴力,即按照做過的事情不再去做來優化 我們知道,乙個回文串要麼是奇數的串 aba 要麼是偶數的串 abba 可以看出,乙個回文串有乙個對稱軸 對於奇數串aba來說,對稱軸就是b 而對於偶數串abba來說,...

Manacher演算法(馬拉車)

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

馬拉車演算法manacher

1.預處理解決奇回文和偶回文問題 比如 str bcbaa 在每個字元的開頭,結尾和中間插入乙個特殊字元 來得到乙個新的字串 b c b a a 這樣對於原來字串中的奇回文 bcb 來說,在新的字串中變成了 b c b 還是奇回文,只是回文串長度從3變成了7 注意 中 i 1 0,與1按位與,如果i...