令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。首先由題意可知,只用考慮偶數長的回文串。這樣就不用插入 直...