BZOJ 2565 最長雙回文串

2021-08-11 06:40:18 字數 1868 閱讀 9540

description

順序和逆序讀起來完全一樣的串叫做回文串。比如acbca是回文串,而abc不是(abc的順序為「abc」,逆序為「cba」,不相同)。

輸入長度為

n 的串s,求

s 的最長雙回文子串

t,即可將

t 分為兩部分x,

y ,(|x

|,|y

|≥1)且

x 和

y都是回文串。

input

一行由小寫英文本母組成的字串

s 。

output

一行乙個整數,表示最長雙回文子串的長度。

sample input

baacaabbacabb

sample output

12hint

樣例說明

從第二個字元開始的字串aacaabbacabb可分為aacaa與bbacabb兩部分,且兩者都是回文串。

對於100%的資料,2≤

|s|≤

105。 2015.4.25新加資料一組

source

2012國家集訓隊round 1 day2

思路

首先maracher跑一遍,然後分別更新乙個點

i 不包含它的左側的最長回文子串和右側的最長回文字串的長度(記為li

和ri ),就拿這個串來說吧:abbab,擴充後得到#b#a#b#b#a#b#這個串,那麼第6個(倒數第2個)#號左側的最長回文字串就是abba,右側的最長回文字串就是b,注意是原串的長度。

那麼計算li

時,由於選擇串需要盡量選擇最長的,就是串的中心越小越好,因此可以從左到右掃一遍,把還沒有計算的都計算了,下次計算時又從還沒有計算的第乙個位置開始計算,這樣能夠確保時間複雜度為o(

n),計算右側時同理。

還有些細節在**中講。

**

#include 

#include

const

int maxn=100000;

char s[maxn+10],a[(maxn<<1)+10];

int p[(maxn<<1)+10],l[(maxn<<1)+10],r[(maxn<<1)+10],id,rmax,len,ans;

int main()

len=len<<1|1;

a[len+1]='*';//預處理

p[1]=id=rmax=1;

for(register

int i=2; i<=len; ++i)//maracher

else

else

}while(a[i+p[i]]==a[i-p[i]])

if(i+p[i]-1>rmax)

}int now=0;//now記錄最後乙個更新的是哪乙個位置

for(register

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

if(i+p[i]+1>now)

}//上一次掃瞄完成後,now一定為n

for(register

int i=len; i>=1; --i)

if(i-p[i]-1

for(register

int i=1; i<=len; i+=2)//只計算預處理時插入的字元

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

return

0;}

bzoj2565 最長雙回文串

傳送門 manacher 奇怪的遞推 我也不清楚這算不算遞推 0.0 大體思路是記錄能到達每個字元的最早的對稱中心,然後根據在manacher的時候用當前回文串和前面相鄰的回文串來更新答案就好了 我邊界問題處理了好久,然而1a開森 code include define n 100005 char ...

BZOJ 2565 最長雙回文串

順序和逆序讀起來完全一樣的串叫做回文串。比如acbca是回文串,而abc不是 abc的順序為 abc 逆序為 cba 不相同 輸入長度為n的串s,求s的最長雙回文子串t,即可將t分為兩部分x,y,x y 1 且x和y都是回文串。一行由小寫英文本母組成的字串s。一行乙個整數,表示最長雙回文子串的長度。...

BZOJ 2565 最長雙回文串

題意 給出乙個字串s ss,求s ss的最長雙回文子串t tt,即可將t tt分為兩部分x xx,y yy,x y 1 x y 1 x y 1 且x xx和y yy都是回文串。題解 我們知道len i len i len i 表示以i ii這個字元結束的最長回文串的長度,然後我們只需要建立兩個回文自...