1. 程式人生 > >BZOJ 2565: 最長雙迴文串

BZOJ 2565: 最長雙迴文串

一開始以為是要上線段樹的(線段樹解法在這裡就不說了吧QAQ),然後發現有 O(n) 做法,妙啊
https://www.cnblogs.com/CQzhangyu/p/6802572.html

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+3;
char O[1<<14],*S=O,*T=O;
#define gc (S==T&&(T=(S=O)+fread(O,1,1<<14,stdin),S==T)?-1:*S++)
char s[N<<1
]; int r[N<<1],L[N<<1],R[N<<1]; int main(){ int n=0,i,mx=0,id,ans=0; while(1){ char c=gc; s[++n]='*'; if(c=='\n'||c<0)break; s[++n]=c; } for(i=1;i<=n;++i){ if(mx>i)r[i]=min(r[id*2-i],mx-i); while(i+r[i]<=n && s[i-r[i]]==s[i+r[i]])++r[i]; --r[i]; if
(i+r[i]>mx)mx=i+r[i],id=i; R[i-r[i]]=max(R[i-r[i]],r[i]); L[i+r[i]]=max(L[i+r[i]],r[i]); } for(i=3;i<=n;i+=2) R[i]=max(R[i],R[i-2]-2); for(i=n-2;i>0;i-=2)L[i]=max(L[i],L[i+2]-2); for(i=1;i<=n;i+=2) ans=max(L[i]+R[i],ans); printf("%d\n",ans); return 0
; }