zoukankan      html  css  js  c++  java
  • UVA11107 Life Forms

    思路

    后缀数组
    先都拼在一起
    二分+height分段
    按照小于x的为分界,判断是否有一个分段中包含超过n/2个串

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    struct Node{
        int pos,r[2];
    }x[200100],midx[200100];
    int n,sa[200100],ranks[200100],barrel[200100],height[200100],belong[200100],has[210],numx;
    char s[200100],c[200100];
    int c_sort(int n,int lim){
        for(int i=0;i<2;i++){
            memset(barrel,0,sizeof(barrel));
            for(int j=1;j<=n;j++)
                barrel[x[j].r[i]]++;
            for(int j=1;j<=lim;j++)
                barrel[j]+=barrel[j-1];
            for(int j=n;j>=1;j--)
                midx[barrel[x[j].r[i]]--]=x[j];
            for(int j=1;j<=n;j++)
                x[j]=midx[j];
        }
        ranks[x[1].pos]=1;
        int cnt=1;
        for(int i=2;i<=n;i++){
            if(x[i].r[0]==x[i-1].r[0]&&x[i].r[1]==x[i-1].r[1])
                ranks[x[i].pos]=cnt;
            else
                ranks[x[i].pos]=++cnt;
        }
        return cnt;
    }
    void cal_sa(int n){
        for(int i=1;i<=n;i++)
            x[i]=(Node){i,s[i],0};
        int cnt=c_sort(n,255);
        for(int i=1;cnt<n;i<<=1){
            for(int j=1;j<=n;j++)
                x[j]=(Node){j,(i+j<=n)?ranks[i+j]:0,ranks[j]};
            cnt=c_sort(n,cnt);
        }
        for(int i=1;i<=n;i++)
            sa[ranks[i]]=i;
        for(int i=1,j=0,k;i<=n;height[ranks[i++]]=j)
            for(j?j--:0,k=sa[ranks[i]-1];s[i+j]==s[j+k];j++);
    }
    // void init(void){
    //     for(int i=1;i<=n;i++)
    //         ST[i][0]=height[i];
    //     for(int i=1;i<20;i++)
    //         for(int j=1;j<=n;j++)
    //             ST[j][i]=min(ST[j][i-1],ST[min(j+(1<<(i-1)),n+10)][i-1]);
        
    // }
    // int query(int l,int r){
    //     l=ranks[l];
    //     r=ranks[r];
    //     l++;
    //     if(l>r)
    //         swap(l,r);
    //     int k=0;
    //     while((1<<k+1)<=(r-l+1))
    //         k++;
    //     return min(ST[l][k],ST[r-(1<<k)+1][k]);
    // } 
    bool check(int x){
        // printf("check %d
    ",x);
        memset(has,0,sizeof(has));
        int midnum=0;
        has[0]=true;
        if(!has[belong[sa[1]]]){
            ++midnum;
            has[belong[sa[1]]]=true;
        }
        if(midnum>(numx/2)){
            return true;
        }
        for(int i=2;i<=n;i++){
            if(height[i]<x){
                memset(has,0,sizeof(has));
                has[0]=true;
                midnum=0;
                if(!has[belong[sa[i]]]){
                    midnum++;
                    has[belong[sa[i]]]=true;
                }
            }
            else{
                if(!has[belong[sa[i]]]){
                    midnum++;
                    has[belong[sa[i]]]=true;
                }
            }
            if(midnum>(numx/2)){
                return true;
            }
        }
        return false;
    }
    void print(int x){
        memset(has,0,sizeof(has));
        int midnum=0,f=1;
        has[0]=true;
        if(!has[belong[sa[1]]]){
            ++midnum;
            has[belong[sa[1]]]=true;
        }
        if(midnum>(numx/2)&&f){
            f=0;
            for(int j=1;j<=x;j++)
                putchar(s[sa[1]+j-1]);
            putchar('
    ');
        }
        for(int i=2;i<=n;i++){
            if(height[i]<x){
                f=1;
                memset(has,0,sizeof(has));
                has[0]=true;
                midnum=0;
                if(!has[belong[sa[i]]]){
                    midnum++;
                    has[belong[sa[i]]]=true;
                }
            }
            else{
                if(!has[belong[sa[i]]]){
                    midnum++;
                    has[belong[sa[i]]]=true;
                }
            }
            if(midnum>(numx/2)&&f){
                f=0;
                for(int j=1;j<=x;j++)
                    putchar(s[sa[i]+j-1]);
                putchar('
    ');
            }
        }
    }
    void init(void){
        memset(s,0,sizeof(s));
        memset(height,0,sizeof(height));
        memset(sa,0,sizeof(sa));
        memset(ranks,0,sizeof(ranks));
        memset(belong,0,sizeof(belong));
        memset(midx,0,sizeof(midx));
        memset(x,0,sizeof(x));
    }
    int main(){
        // freopen("test.in","r",stdin);
        // freopen("test.out","w",stdout);
        int cnt=0;
        while(scanf("%d",&numx)==1&&numx){
            init();
            n=0;
            cnt++;
            if(cnt>1)
                putchar('
    ');
            if(numx==1){
                scanf("%s",s);
                printf("%s
    ",s);
                continue;
            }
            for(int i=1;i<=numx;i++){
                scanf("%s",c+1);
                int len=strlen(c+1);
                for(int j=1;j<=len;j++){
                    s[n+j]=c[j];
                    belong[n+j]=i;
                }
                n+=len;
                s[++n]='z'+i;
                belong[n]=0;
            }
            // for(int i=1;i<=n;i++)
            //     putchar(s[i]);
            // putchar('
    ');
            cal_sa(n);
            // for(int i=1;i<=n;i++){
            //     printf("%d ",height[i]);
            // }
            // printf("
    ");
            // for(int i=1;i<=n;i++){
            //     printf("%d ",belong[sa[i]]);
            // }
            // printf("
    ");
            // printf("ok
    ");
            int l=0,r=n,ans=0;
            while(l<=r){
                int mid=(l+r)>>1;
                if(check(mid))
                    l=mid+1,ans=mid;
                else
                    r=mid-1;
            }
            // printf("ans=%d
    ",ans);
            if(ans==0){
                printf("?
    ");
            }
            else{
                print(ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    SQL 连接
    nvl() 数值替换函数 oracle使用
    Oracle 中sql语句中的取前n条数据
    设置序列
    Oracle创建用户 创建表空间 分配权限
    oracle11 刚刚安装后提示invalid username password logon denied
    关于index 索引
    事物
    数据库 oracle 设计三范式
    TXT编写程序-编译-执行流程
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10708688.html
Copyright © 2011-2022 走看看