zoukankan      html  css  js  c++  java
  • ural1297

    题解:

    后缀数组

    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;
    }
  • 相关阅读:
    python3字典删除元素和添加元素的几种方法
    查看ef core 3.1/3.0/2.1.2生成的sql语句
    C#Qrcode生成二维码支持带标题
    .net RabbitMQ 介绍、安装、运行
    Golang之初探
    MySql5.7多实例配置教程
    Centos7 安装MySql 5.7
    sqlserver智能提示插件-sql prompt(9.4.6)的安装及注册流程
    ABP框架(asp.net core 2.X+Vue)模板项目学习之路(二)--切换MySql数据库
    ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一)
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8550636.html
Copyright © 2011-2022 走看看