P4287 [SHOI2011]雙倍迴文
阿新 • • 發佈:2021-02-17
文章目錄
R e s u l t Result Result
H y p e r l i n k Hyperlink Hyperlink
https://www.luogu.com.cn/problem/P4287
D e s c r i p t i o n Description Description
若一個迴文串長度為4的倍數且從中間斷開後的兩個子串仍是迴文串稱這個串是雙倍迴文的。給定一個長度為
n
n
n的串,求其最長雙倍迴文子串
資料範圍:
n
≤
5
×
1
0
5
n\leq 5\times 10^5
n≤5×105
S o l u t i o n Solution Solution
跑馬拉車時順便判斷前面是否能拓展過來即可
時間複雜度: O ( n ) O(n) O(n)
C o d e Code Code
#include<cstdio>
#include <cctype>
#include<cstring>
#include<algorithm>
#define LL long long
#define N 5000010
using namespace std;char s[N],news[N];
int n,newn,p[N];
inline LL read()
{
char c;LL d=1,f=0;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit (c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void Init()
{
news[0]='~';news[1]='|';newn=2;
for(register int i=0;i<n;i++) news[newn++]=s[i],news[newn++]='|';
news[newn]=10;return;
}
inline int Manacher()
{
int mid=1,mx=1,ans=0;
for(register int i=1;i<newn;i++)
{
if(i<mx) p[i]=min(mx-i,p[2*mid-i]);else p[i]=1;
while(news[i-p[i]]==news[i+p[i]]) p[i]++;
if(mx<i+p[i])
{
if(i&1) for(register int j=max(mx,i+4);j<i+p[i];j++) if(!(j-i&3)&&p[i-(j-i)/2]>(j-i)/2) ans=max(ans,j-i);
mid=i;
mx=i+p[i];
}
}
return ans;
}
signed main()
{
n=read();scanf("%s",s);Init();
printf("%d\n",Manacher());
}