BZOJ 2565: 最长双回文串

版权声明:本文为一名蒟蒻的原创文章,大神转载的话顺便说个出处呗。 https://blog.csdn.net/cgh_Andy/article/details/78878279

一开始以为是要上线段树的(线段树解法在这里就不说了吧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;
}


猜你喜欢

转载自blog.csdn.net/cgh_Andy/article/details/78878279