BZOJ2565 最長雙回文串 題解

2022-05-16 16:31:23 字數 1166 閱讀 3264

題目大意:

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

輸入長度為n的串s,求s的最長雙回文子串t,即可將t分為兩部分x,y,(|x|,|y|≥1)且x和y都是回文串。

——————————————————————

看到回文串長度最大,先敲乙個manacher演算法。

然後思考如何更新每乙個字元以其為起點和終點的最長回文串。

顯然都跑一遍肯定是不行的(嘗試過tle…)

那麼我們考慮乙個很簡單的事實,對於乙個在某幾個回文串的字元,顯然當它屬於mx靠前的回文串時以它為終點的回文串長度最長。

那麼我們就有了一種近似o(n)的演算法,通過記錄我們最新一次更新的字元位置now,然後搜尋每乙個回文串,當回文串右端點超過了now的時候,就對now和右端點之間的字元更新。

同理處理另一種情況,然後列舉取最大值即可。

ps:我們已知回文串的中點i,怎麼求在回文串內的j以其為終點的回文串長度。

我們有結論為j-i+1,簡易證明:

我們知道我們最開始的時候是含有「#」插入的字串處理,此時回文串的長度為2*(j-i)+1.

而實際上其中包含了「#」有j-i個(就是長度/2向下取整)。

相減得到j-i+1。

#include#include

#include

#define n 100010

using

namespace

std;

int left[2*n],right[2*n],mx,id,p[2*n];

char s[2*n];

intmain()

}int now=0

;

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

now=i+p[i]-1

; }

}now=l+1

;

for(int i=l;i>=1;i--)

now=i-p[i]+1

; }

}int ans=0

;

for(int i=2;i<=l;i+=2

) printf(

"%d\n

",ans);

return0;

}

bzoj2565 最長雙回文串

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

BZOJ 2565 最長雙回文串

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

BZOJ 2565 最長雙回文串

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