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;
}

  

posted @ 2016-09-08 19:04  北北北北屿  阅读(127)  评论(0编辑  收藏  举报