Hdu 3068最長回文 Manacher演算法

2021-08-01 13:23:36 字數 1059 閱讀 6853

這是一種能夠在將近o(n)的時間裡求出給定字串的最長回文子串的演算法。

首先我們知道字串的長度分奇偶,這對我們考慮問題影響很大,所以在給定字串的所有字元之間插入乙個無關字元(包括首尾),這樣對答案沒有什麼影響,而且字串的長度都變為n*2+1,是個奇數。

然後定義乙個f陣列,f[i]表示以i為中心向右/向左擴充套件的長度(包括i),定義mx,id,表示以id為中心的子串是當前右邊界最大的回文串,右邊界為mx。

那麼顯然有mx

=f[i

d]+i

d mx=

f[id

]+id

i在id的右邊,那麼如果i

<

<

mx,就肯定存在i關於id 的乙個對稱點j=2*id-i,並且f[i]>=min(f[j],i-mx)。否則f[i]只能先給1了。

看看下面這張圖顯然能夠明白:

manacher演算法是利用已知的回文子串減少大量的冗餘的計算,所以效率非常好,將近o(n)。

下面以hdu 3068為例給出**

#include

#include

#include

using

namespace

std;

const

int maxn=220005;

char s[maxn];

int f[maxn],n,ans,mx,id;

void manacher()

for (int i=1; i<=n; i++) ans=max(ans,f[i]-1);

printf("%d\n",ans);

}int main()

while (ch>='a'&&ch<='z') s[++n]=ch,n++,ch=getchar();

manacher();

}return

0;}

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