ural 1713

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <string>

using namespace std;

#define N 201000
#define M 110
int wa[N],wb[N],wv[N],wt[N];
int cmp(int r[],int a,int b,int l)
{
    return r[a]==r[b] && r[a+l]==r[b+l];
}
void SuffixArry(int r[],int sa[],int rannkk[],int height[],int n,int m)
{
    int i,j,k,p,*x=wa,*y=wb,*t;
    for(i=0;i<m;i++) wt[i]=0;
    for(i=0;i<n;i++) wt[x[i]=r[i]]++;
    for(i=1;i<m;i++) wt[i]+=wt[i-1];
    for(i=n-1;i>=0;i--) sa[--wt[x[i]]]=i;
    for(j=1,p=1;p<n;j*=2,m=p)
    {
        for(p=0,i=n-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++) wt[i]=0;
        for(i=0;i<n;i++) wt[wv[i]]++;
        for(i=1;i<m;i++) wt[i]+=wt[i-1];
        for(i=n-1;i>=0;i--) sa[--wt[wv[i]]]=y[i];
        for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
            x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    }
    for(i=0;i<n;i++) rannkk[sa[i]]=i;
    for(i=k=0;i<n-1;height[rannkk[i++]]=k)
        for(k?k--:0,j=sa[rannkk[i]-1];r[i+k]==r[j+k];k++);
}
int sa[N],rannkk[N],height[N];
char s[1001][M];
int know[1001][M];
int memory[N],cnt[N];
int r[N];
int lmin[N],rmin[N];
int len[1001];
struct node
{
    int index,len;
}des[1001];
int mark[1001],visit[M];
int main() {
//    freopen("in","r",stdin);
    //freopen("out","w",stdout);
    int nq,n,m;
    while(~scanf("%d",&nq))
    {
        int i,j,k;
        m=30;
        for(k=i=0;k<nq;k++)
        {
            scanf("%s",s[k]);
            for(j=0;s[k][j];j++)
            {
                memory[i] = k;
                cnt[i] = j;
                know[k][j] = i;
                r[i++]=s[k][j]-'a'+1;
            }
            len[k]=j;
             memory[i] = cnt[i] = 1100;
            r[i++]=m++;
        }
        n=i;
        r[n-1]=0;
        SuffixArry(r,sa,rannkk,height,n,m);

        memset(mark,0,sizeof(mark));
        for(k=0;k<nq;k++)
        {
            memset(visit,0,sizeof(visit));
            int left,right;

            for(i=0;i<len[k];i++)
            {
                left=rannkk[know[k][i]];
                while(memory[sa[left-1]]==k) left--;


                right=rannkk[know[k][i]]+1;
                while(memory[sa[right]]==k) right++;
                              
                lmin[left] = height[left];
                for(j=left;j<right;j++)
                {
                    visit[cnt[sa[j]]]=1;
                }
                
                for(j=left+1;j<right;j++)
                    lmin[j]=min(lmin[j-1],height[j]);
                rmin[right-1] = height[right];
                for(j=right-2;j>=left;j--)
                    rmin[j]=min(rmin[j+1],height[j+1]);
                for(j=left;j<right;j++)
                {
                    int Max=max(lmin[j],rmin[j]);
                    int ll=len[k]-cnt[sa[j]];
                    if(Max==ll) continue;
                    if(mark[k]==0)
                    {
                        des[k].index=cnt[sa[j]];
                        des[k].len=Max+1;
                        mark[k]=1;
                    }
                    else if(Max<des[k].len)
                    {
                        des[k].index=cnt[sa[j]];
                        des[k].len=Max+1;
                    }
                }

            }
        }
        for(i=0;i<nq;i++)
        {
            for(j=0;j<des[i].len;j++)
                putchar(s[i][des[i].index+j]);
            printf("\n");
        }
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值