欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

URAL 1297 SA

程序员文章站 2024-01-12 16:22:28
...

URAL 1297

题意 求回文串 跟求在两个串里面的最长公共子串求法一样 但是要特判 n-maxx!=height[i]+minn 的时候需要continue掉 因为对着的位置不同 就不能回文

/*
    if you can't see the repay
    Why not just work step by step
    rubbish is relaxed
    to ljq
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
const ll mod =  (int)1e9+7;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
const int MAX_N = 2e3+5;
int wa[MAX_N],wb[MAX_N],wsf[MAX_N],wv[MAX_N],sa[MAX_N];
int Rank[MAX_N],height[MAX_N],s[MAX_N];
char str1[MAX_N],str2[MAX_N];
int cmp(int *r,int a,int b,int k)
{
    return r[a]==r[b]&&r[a+k]==r[b+k];
}
void getsa(int *r,int *sa,int n,int m)//n为添加0后的总长
{
    int i,j,p,*x=wa,*y=wb,*t;
    for(i=0; i<m; i++)  wsf[i]=0;
    for(i=0; i<=n; i++)  wsf[x[i]=r[i]]++;
    for(i=1; i<m; i++)  wsf[i]+=wsf[i-1];
    for(i=n; i>=0; i--)  sa[--wsf[x[i]]]=i;
    p=1;
    j=1;
    for(; p<=n; j*=2,m=p)
    {
        for(p=0,i=n+1-j; i<=n; i++)  y[p++]=i;
        for(i=0; i<=n; i++)  if(sa[i]>=j)  y[p++]=sa[i]-j;
        for(i=0; i<=n; i++)  wv[i]=x[y[i]];
        for(i=0; i<m; i++)  wsf[i]=0;
        for(i=0; i<=n; i++)  wsf[wv[i]]++;
        for(i=1; i<m; i++)  wsf[i]+=wsf[i-1];
        for(i=n; i>=0; i--)  sa[--wsf[wv[i]]]=y[i];
        t=x;
        x=y;
        y=t;
        x[sa[0]]=0;
        for(p=1,i=1; i<=n; i++)
            x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++;
    }
}

void getheight(int *r,int n)//n为添加0后的总长
{
    int i,j,k=0;
    for(i=1; i<=n; i++)  Rank[sa[i]]=i;
    for(i=0; i<n; i++)
    {
        if(k)
            k--;
        else
            k=0;
        j=sa[Rank[i]-1];
        while(r[i+k]==r[j+k])
            k++;
        height[Rank[i]]=k;
    }
}
int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    scanf("%s",str1);
    int len = strlen(str1),n=0,ans = 1,xb=0;
    for(int i = 0;i<len;++i)
        str2[i] = str1[len-i-1];
    for(int i = 0;i<len;++i)
        s[n++] = str1[i]-'A'+1;
    s[n++] = 60;
    for(int i = 0;i<len;++i)
        s[n++] = str2[i]-'A'+1;
    s[n] = 0;
    getsa(s,sa,n,70);
    getheight(s,n);
    for(int i = 2;i<=n;++i)
    {
        int maxx = max(sa[i],sa[i-1]);
        int minn = min(sa[i],sa[i-1]);
        if(maxx<len||minn>len) continue;
        if(n-maxx != height[i]+minn) continue;
                if(height[i]>ans)
                {
                    xb  = min(sa[i],sa[i-1]);
                    ans = height[i];
                }
                else if(height[i]==ans)
                {
                xb = min(xb,min(sa[i],sa[i-1]));
                }

    }
    for(int i = xb;ans--;++i)
        printf("%c",s[i]-1+'A');
    printf("\n");
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}