BZOJ 2342: [Shoi2011]双倍回文
Sol
Manacher.
非常裸的Manacher啊...为什么有那么多人写Manacher+并查集?Set?Treap?...好神奇...
你只需要在 \(p[i]++\) 的位置加上判断就可以了,不需要任何数据结构维护答案...
你要保证两个点都在'#'字符上就可以了...
Code
/************************************************************** Problem: 2342 User: BeiYu Language: C++ Result: Accepted Time:92 ms Memory:6172 kb ****************************************************************/ #include<cstdio> #include<iostream> using namespace std; const int N = 500050; int n,ans; char s[N<<1]; int p[N<<1]; inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar(); while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; } inline char mychar(char ch=getchar()){ while(ch>'z'||ch<'a') ch=getchar();return ch; } int main(){ // freopen("in.in","r",stdin); n=in();s[0]='$',s[1]='#'; for(int i=1;i<=n;i++) s[i<<1]=mychar(),s[i<<1|1]='#'; int mx=0,id=0;n=n<<1|1; for(int i=1;i<=n;i+=2){ if(mx>i) p[i]=min(p[id+id-i],mx-i);else p[i]=1; for(int t;s[i-p[i]]==s[i+p[i]];p[i]++) if(p[i]>=2&&((i-p[i])&1)){ t=(i+i-p[i])/2; if(t&1) if(t+p[t]>=i) ans=max(ans,p[i]); } if(i+p[i]>mx) mx=i+p[i],id=i; } cout<<ans<<endl; return 0; }