luogu P4287 [SHOI2011]双倍回文
题面传送门
蛮好的一道题,可惜我不会证(
有回文串那么考虑Manacher
首先手玩一下就能发现,如果在右半边更新答案,那么当前答案右端点一定过当前右端点
然后再手玩就能发现,如果当前左端点过当前最大中点,那么就是可以更新答案的。这样肯定最大,然后就完了。
代码实现:
#include<cstdio>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
int n,a[1000039],head,mid,mr,f[1000039],ans;
char s[1000039],_s;
int main(){
freopen("1.in","r",stdin);
register int i;
scanf("%d",&n);s[++head]='@';s[++head]='#';
for(i=1;i<=n;i++){
_s=getchar();
while(_s<'a'||_s>'z') _s=getchar();
s[++head]=_s;s[++head]='#';
} s[++head]='~';
mr=mid=1;
for(i=2;i<=head;i+=2){
f[i]=(i<=mr?min(f[2*mid-i],mr-i):1);
if(mr>i&&i-f[i]<=mid)ans=max(ans,(i-mid)*2);
while(s[i+f[i]]==s[i-f[i]]) f[i]++;
if(i+f[i]>mr) mr=i+f[i],mid=i;
}
printf("%d\n",ans);
}