zoukankan      html  css  js  c++  java
  • 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;  
    }  
  • 相关阅读:
    设计模式-抽象工厂模式
    装修预算-资料收集
    SQL中存储过程和函数的区别
    View
    数据表优化
    Entity Framework 基础
    html5标准
    JS整数验证
    vue 页面切换从右侧切入效果
    vue动态设置Iview的多个Input组件自动获取焦点
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8535184.html
Copyright © 2011-2022 走看看