• spoj220


    题解:

    后缀数组

    把所有串连接起来

    二分答案

    代码:

    #include<cstdio>  
    #include<cstring>  
    #include<algorithm>  
    #include<cmath>  
    const int N=200005;
    typedef long long ll;
    using namespace std;
    char ch[N];  
    int str[N],l[N],mx[N],mn[N],in[N],k,wa[N],wb[N],wv[N],Ws[N],sa[N],Rank[N],height[N];
    int cmp(int *r,int a,int b,int l)    
    {
        return r[a]==r[b]&&r[a+l]==r[b+l];
    }    
    void da(const int *r,int *sa,int n,int m)
    {    
        int *x=wa,*y=wb;     
        for (int i=0;i<m;i++) Ws[i]=0;     
        for (int i=0;i<n;i++) Ws[x[i]=r[i]]++;     
        for (int i=1;i<m;i++) Ws[i]+=Ws[i-1];     
        for (int i=n-1;i>=0;i--) sa[--Ws[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++) Ws[i]=0;     
            for (int i=0;i<n;i++) Ws[wv[i]]++;     
            for (int i=1;i<m;i++) Ws[i]+=Ws[i-1];     
            for (int i=n-1;i>=0;i--) sa[--Ws[wv[i]]]=y[i];
            swap(x,y);p=1;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(const int *r,int *sa,int n)
    {    
        int j,k=0;    
        for (int i=1;i<=n;i++) Rank[sa[i]]=i;    
        for (int i=0;i<n;height[Rank[i++]]=k)    
         for (k?k--:0,j=sa[Rank[i]-1];r[i+k]==r[j+k];k++);      
    }  
    int pd(int mid,int n)
    {  
        for (int i=0;i<k;i++){mx[i]=0;mn[i]=1e9;}   
        for (int i=1;i<=n;i++)
         {  
            if (height[i]<mid)
             {  
                for (int j=0;j<k;j++)
                 {  
                    mx[j]=0;  
                    mn[j]=1e9;  
                 }  
                mx[in[sa[i]]]=sa[i];  
                mn[in[sa[i]]]=sa[i];  
             }  
            else
             {  
                mx[in[sa[i]]]=max(mx[in[sa[i]]],sa[i]);  
                mn[in[sa[i]]]=min(mn[in[sa[i]]],sa[i]);  
                mx[in[sa[i-1]]]=max(mx[in[sa[i-1]]],sa[i-1]);  
                mn[in[sa[i-1]]]=min(mn[in[sa[i-1]]],sa[i-1]); 
                int j; 
                for (j=0;j<k;j++)
                 if (mx[j]-mn[j]<mid)break;
                if (j==k) return 1;  
             }  
         }  
        return 0;  
    }  
    int main()
    {  
        int cnt=0,t;  
        scanf("%d",&t);  
        while (t--)
         {  
            scanf("%d",&k);  
            int n=0;  
            for (int i=0;i<k;i++)
             {  
                scanf("%s",ch);  
                l[i]=strlen(ch);  
                for (int j=n;j<n+l[i];j++)
                 {  
                    str[j]=ch[j-n]-'a'+1;  
                    in[j]=i;  
                 }  
                n+=l[i]+1;  
                str[n-1]=27+i;  
             }  
            n--;  
            str[n]=0;  
            da(str,sa,n+1,27+k+5);  
            calheight(str,sa,n);  
            int l=0,r=10000;  
            while (l<r)
             {  
                int mid=(l+r+1)/2;  
                if (pd(mid,n))l=mid; 
                else r=mid-1;  
             }  
            printf("%d
    ",l);  
         }  
        return 0;  
    }  
  • 相关阅读:
    促仅开发者间交流与合作的胡思乱想
    Unity3D音乐音效研究-MIDI与波表
    剑英陪你玩转图形学 (二)彩虹
    java mail实现Email的发送,完整代码
    linux 下 安装 rpm 格式 的 mysql
    ExtJs3带条件的分页查询的实现
    查看linux的版本信息
    java 非法字符过滤 , 半角/全角替换
    MySQL数据库错误server_errno=2013的解决
    MySQL数据库双机热备份
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8535184.html
Copyright © 2020-2023  润新知