HDU 3068 最長回文

2022-02-16 22:44:18 字數 1016 閱讀 4588

這題好像只能用mancher演算法解決,速成馬拉車演算法。

這個演算法的核心思想就是,如果當前要維護的下標i小於上一次經維護後的max值,我們就取上一次得到的對稱位置的回文半徑。

這個回文半徑就是min(p[ id * 2 - i] , max-i),它的意思就代表了,我們先取其中最小的乙個半徑,然後我們之後再暴力向後拓展。

因為我們下一步是暴力,所以我們上一步取乙個小值即可。括號中的兩個表示式的意思是,它的對稱位置 由 中心位置

id-(i-id) 得到,所以就取它對稱位置的回文半徑值,要麼就是上次拓展的最大位置減去i值,它們兩個中取乙個最小值,

這樣我們就不必暴搜之前的那麼多次了。我們只用搜尋之後的就可了。

但是在我們維護之前,我們可以看到,如果我們維護奇數長度的子串的時候,還是很方便的,所以當我們維護偶數長度的時候,我們就把偶數變奇數即可。

我們在每次字元之間加上乙個#,這樣的話,如果是偶數長度,中間就有奇數個間隙,左右兩邊共有兩個#,偶數加偶數加奇數,就是奇數。對於奇數長度同理。

然後我們求的這個陣列p裡面求的其實是半徑值,而我們之前把原子串擴充套件了1倍,所以而我們求的半徑值減一就是原子串的直徑。

這就是馬拉車演算法的思路,其實和kmp還是蠻像的。

#include

#include

const

int maxn =

3e5;

char s[maxn]

, str[maxn]

;int len1, len2, p[maxn]

, ans;

intmin

(int x,

int y)

void

init()

len2 = len1 *2+

2;str[len2]

='*';}

void

manacher()

}}intmain()

printf

("%d\n"

, ans-1)

;}}

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之間由空行...