最長回文(HDU 3068)

2021-09-14 00:08:34 字數 2564 閱讀 5014

下面先介紹man

ache

rmanacher

manach

er演算法。假設str

strst

r為待處理字串,len

[i

]len[ i ]

len[i]

陣列存放以該str

[i

]str[ i ]

str[i]

字元為中心的最長回文半徑,mid

midmi

d為當前最長回文子串的中點,mxmx

mx為當前最長回文子串的右邊界.。

在開始演算法之前,先在字串中首部填充$,字元之間#。比如,字串abaaba填充之後就變成了$#a#b#a#a#b#a#($與#未在字串**現)。

那麼對當前位置 i

ii有如下偽**:(此時已經知道前i−1

i - 1

i−1個字元的最長回文半徑)

若i

i < mx

i,則l en

[i]=

min(

len[

2×mi

d−i]

,mx−

i)

len[ i ] = min ( len[ 2 \times mid - i ] , mx - i )

len[i]

=min

(len

[2×m

id−i

],mx

−i)。

否則l en

[i]=

1len[ i ] = 1

len[i]

=1。對i

ii位置上的字元向兩邊進行匹配,更新len

[i

]len[ i ]

len[i]

的值,更新結束後更新mid

midmi

d和mx

mxmx

的值。

命題:如果i

i < mx

i,那麼i

ii為中心的最長回文半徑最少為min

(len

[2×m

id−i

],mx

−i

)min ( len[ 2 \times mid - i ] , mx - i )

min(le

n[2×

mid−

i],m

x−i)

證明

首先i

i < mx

i說明i

ii坐落於以mid

midmi

d為中心的回文子串中。在該回文子串範圍內,左右兩邊是完全對稱的,所以i

ii的最長回文半徑可參考其對稱點2×m

id−i

2 \times mid - i

2×mid−

i的最長回文半徑。

已知其對稱點2×m

id−i

2 \times mid - i

2×mid−

i最長回文半徑為min

(len

[2×m

id−i

],mx

−i

)min ( len[ 2 \times mid - i ] , mx - i )

min(le

n[2×

mid−

i],m

x−i)

,所以i

ii的最長回文半徑至少為min

(len

[2×m

id−i

],mx

−i

)min ( len[ 2 \times mid - i ] , mx - i )

min(le

n[2×

mid−

i],m

x−i)

,超出mxmx

mx的部分暴力匹配即可。

$#a#b#a#a#b#a#中以#為中心的最長回文子串去掉#後對應原字串的最長偶回文串,以原字元為中心的最長回文子串去掉#後對應原字串的最長奇回文串。而去掉#後的最長回文串的長度正好等於回文半徑減1

11,這樣問題轉化為了求$#a#b#a#a#b#a#的最長回文半徑。

由於每個字元只會被匹配一次,所以時間複雜度為o(n

)\mathcal(n)

o(n)

#include

#include

#include

#include

using

namespace std;

const

int maxn=

110010

;char s[maxn]

,ma[maxn*2]

;int mp[maxn*2]

;int

manacher

(char

*s,int len)

return res;

}int

main()

return0;

}

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