题解:

后缀数组

st表处理加速lcp

把串后面加一个不可能出现的字符

然后再把串倒过来放在后面

暴力枚举中心

判断lcp

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2010;
int ws1[N],wv[N],wa[N],wb[N],rank1[N],height[N],sa[N],a[N],n,dp[N][25];
char str[N];
int cmp(int *r,int a,int b,int l)
{
    return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(int *r,int *sa,int n,int m)
{
    int *x=wa,*y=wb;
    for (int i=0;i<m;i++)ws1[i]=0;
    for (int i=0;i<n;i++)ws1[x[i]=r[i]]++;
    for (int i=1;i<m;i++)ws1[i]+=ws1[i-1];
    for (int i=n-1;i>=0;i--)sa[--ws1[x[i]]]=i;
    for (int j=1,p=1;p<n;j*=2,m=p)
     {
         p=0;
        for (int i=n-j;i<n;i++)y[p++]=i;
        for (int i=0;i<n;i++)
         if (sa[i]>=j)y[p++]=sa[i]-j;
        for (int i=0;i<n;i++)wv[i]=x[y[i]];
        for (int i=0;i<m;i++)ws1[i]=0;
        for (int i=0;i<n;i++)ws1[wv[i]]++;
        for (int i=1;i<m;i++)ws1[i]+=ws1[i-1];
        for (int i=n-1;i>=0;i--)sa[--ws1[wv[i]]]=y[i];
        p=1;swap(x,y);x[sa[0]]=0;
        for (int i=1;i<n;i++)x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    }
}
void calheight(int *r,int *sa,int n)
{
    int j,k=0;
    for (int i=1;i<=n;i++)rank1[sa[i]]=i;
    for (int i=0;i<n;height[rank1[i++]]=k)
     for (k?k--:0,j=sa[rank1[i]-1];r[i+k]==r[j+k];k++);
}
void RMQ()
{
    memset(dp,127,sizeof(dp));
    for (int i=1;i<=n*2+1;i++)dp[i][0]=height[i];
    for (int j=1;(1<<j)<=2*n+1;j++)
     for (int i=1;i+(1<<j)-1<=2*n+1;i++)
      dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int lcp(int l,int r)
{
    int a=rank1[l],b=rank1[r];
    if (a>b)swap(a,b);
    a++;
    int t=(int)(log(double(b-a+1))/log(2.00));
    return min(dp[a][t],dp[b-(1<<t)+1][t]);
}
int main()
{
    int res,flag,max;
    while (~scanf("%s",str))
     {
        max=0;
        n=strlen(str);
        for (int i=0;i<n;i++)a[i]=(int)str[i];
        a[n]=1;
        for (int i=0;i<n;i++)a[i+n+1]=int(str[n-i-1]);
        a[2*n+1]=0;
        da(a,sa,n*2+2,123);
        calheight(a,sa,2*n+1);
        RMQ();
        for (int i=0;i<n;i++)
         {
            res=lcp(i,2*n-i)*2-1;
            if (max<res)
             {
                max=res;
                flag=i;
             }
            if (i>0)
             {
                res=lcp(i,2*n-i+1)*2;
                if (max<res)
                 {
                    max=res;
                    flag=i;
                 }
             }
         }
        if (max%2==1)
         for (int i=flag-max/2;i<=flag+max/2;i++)printf("%c",str[i]);
        else
         for (int i=flag-max/2;i<=flag+max/2-1;i++)printf("%c",str[i]);
        puts("");
     }
    return 0;
}

 

posted on 2018-03-12 17:49  宣毅鸣  阅读(131)  评论(0编辑  收藏  举报