bzoj 2342 Shoi2011 雙倍回文

2021-08-18 06:49:03 字數 993 閱讀 4037

令w(r)表示字串w的反串

給出乙個字串,問其中最長的ww(r)ww(r)的長度是多少.

求的字串是個回文串,而且可以分成兩個一樣的偶數長度的字串,那麼可以考慮列舉兩個相同字串中間的空隙x並考慮右邊那個字串中間的空隙y的最大值.

首先用馬拉車演算法預處理出mx陣列表示以某個空隙為中間的回文串的長度的一半,根據回文串的性質,不難得出以i為中心,長度的一半小於mx[i]的字串也是回文串,因此可以合法回文串需要滿足以下條件:

1.y-x<=mx[y] —–> y-mx[y]<=x

2.2*(y-x)<=mx[x]—–>y<=mx[x]/2+x

也就是說可以先根據y-mx[y]排序,對於每個x,將x-1與x之間的y-mx[y]加入set,每次利用upper_bound找到目前set中小於等於mx[x]/2+x的最大y來不斷更新答案即可.

#include

#include

#include

#include

#include

#define n 500100

using

namespace

std;

int n,tmp[n<<1],mx[n],ans,num[n],root,tt,mid,r;

char str[n],a[n<<1];

setse;

set::iterator it;

inline

bool cmp(int u,int v)

n=n*2+1;

a[0]='$',a[1]='*',a[n+1]='&';

for(i=1; i<=n; i++)

}for(i=3; i2)

n=n/2-1;

for(i=1; i<=n; i++)

sort(num+1,num+n+1,cmp);

for(i=1,j=1; i<=n; i++)

cout

<}

雙倍回文 Shoi2011 bzoj2342

time limit 10 sec memory limit 128 mb submit 2820 solved 1088 submit status discuss 輸入分為兩行,第一行為乙個整數,表示字串的長度,第二行有個連續的小寫的英文本元,表示字串的內容。輸出檔案只有一行,即 輸入資料中字串...

bzoj 2342 Shoi2011 雙倍回文

題目大意 演算法一 因為雙倍回文串必定是乙個回文串 所以先用manachar求出每個點能夠擴充套件出的最長的回文串長度f i 再列舉對稱軸x,對於y只要滿足y f y x y x f x 2,就可以用len x,y 4來更新答案 對於每個x,只需要用距離其最遠的滿足條件的y來更新即可 將其按i f ...

SHOI2011 bzoj2342 雙倍回文

description input 輸入分為兩行,第一行為乙個整數,表示字串的長度,第二行有個連續的小寫的英文本元,表示字串的內容。output 輸出檔案只有一行,即 輸入資料中字串的最長雙倍回文子串的長度,如果雙倍回文子串不存在,則輸出0。首先由題意可知,只用考慮偶數長的回文串。這樣就不用插入 直...