HDU 3068 最長回文 Manacher演算法

2022-09-24 01:42:08 字數 1085 閱讀 1112

manacher演算法是個解決palindrome問題的o(n)演算法,可以說是個超級演算法了,秒殺其他一切palindrome解決方案,包括複雜的字尾陣列。

這裡總結一下思想重點:

1 原字串的字元間插入新的字元, 如#,方便統一所有的字元中心,比如aa和aba的字元中心不一樣的,aa的字元中心可以說是aa,而aba的中心則是b,而插入#之後,aa成#a#a#,其中心是乙個字元#,而aba插入#a#b#a#,中心還是乙個字元b。

2 充分利用前面已經計算出的資訊來計算後面的資訊,這裡主要利用palindrome的對稱性的特性,那麼就可以利用對稱中心前半段的資訊計算後半段的資訊了。這個是優化演算法到o(n)的關鍵。 因為對稱中心是不斷右移的,故此在對稱中心內的求解只需直接copy前半段的資訊就可以,而超出當前對稱範圍的就需要expand palindrome了。

3 防止溢位,前面加乙個額外的特殊字元,如'~',和前面的插入字元不一樣。後面也需要插入字元,但是為什麼很多程式不插入字元呢?那是因為c++的char都是以''結束的,故此,不插入也是可以的,下面程式明顯插入''到結尾了。

4 需要維護最右點資訊,中心資訊和p陣列,p陣列的含義是以i點為中心的最長palindrome子字串的長度,這裡是長度+1,方便計算。

關鍵**就幾行,但是思想卻是十分難的。

#include

#include

const int max_2l = 220010;

char txt[max_2l];

int p[max_2l];

int len;

inline int min(int a, int b)

inline int max(int a, int b)

void preprocess()

txt[0] = '~';

}int main()

{ while (gets(txt))

{ preprocess();

len = len << 1 | 1;

int maxlen = 0, right = 0, center = 0;

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

{ p[i] = i

HDU 3068 最長回文

題 目 鏈 接 看完後自己寫了一遍,感覺真的是很神奇的結論啊!本來這題看到可以用字尾陣列來寫的,但沒有學過,去看了一下,真心給暈了,決定找個機會認真研究下。我的 include include includeusing namespace std define min a,b a b a b cha...

HDU 3068 最長回文

存在o n 的演算法,學習了一下 include include includeusing namespace std const int maxn 300011 int n,p maxn char str maxn in maxn int main str 0 str 1 n n 2 2 str ...

HDU 3068 最長回文

problem description 給出乙個只由小寫英文本元a,b,c.y,z組成的字串s,求s中最長回文串的長度.回文就是正反讀都是一樣的字串,如aba,abba等 input 輸入有多組case,不超過120組,每組輸入為一行小寫英文本元a,b,c.y,z組成的字串s 兩組case之間由空行...