• Milk Patterns(poj 3261)


    题意:找出出现k次的可重叠的最长子串的长度。

    /*
        求出height数组,二分答案,将height分组,看有没有一组个数大于K。 
        WA了很多遍,最后看别人的题解,发现往字符串后面填了一个0,就可以AC了,不知道为什么。 
    */
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #define N 100010
    using namespace std;
    int s[N],sa[N],rk[N],ht[N],t1[N],t2[N],c[N],n,K;
    struct node{
        int x,id;
        bool operator<(const node&a)const{
            if(x==a.x) return id<a.id;
            return x<a.x;
        }
    }r[N];
    bool cmp(int *y,int a,int b,int k){
        int a1=y[a],b1=y[b];
        int a2=a+k<n?y[a+k]:-1;
        int b2=b+k<n?y[b+k]:-1;
        return a1==b1&&a2==b2;
    }
    void DA(){
        int *x=t1,*y=t2,m=1;n++;
        sort(r,r+n);
        for(int i=0;i<n;i++) sa[i]=r[i].id;
        x[sa[0]]=0;
        for(int i=1;i<n;i++) x[sa[i]]=(r[i].x==r[i-1].x?m-1:m++);
        for(int k=1,p=0;k<=n;k*=2,m=p,p=0){
            for(int i=n-k;i<n;i++) y[p++]=i;
            for(int i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
            for(int i=0;i<m;i++) c[i]=0;
            for(int i=0;i<n;i++) c[x[y[i]]]++;
            for(int i=1;i<m;i++) c[i]+=c[i-1];
            for(int i=n-1;~i;i--) sa[--c[x[y[i]]]]=y[i];
            
            swap(x,y);p=1;x[sa[0]]=0;
            for(int i=1;i<n;i++)
                if(cmp(y,sa[i-1],sa[i],k)) x[sa[i]]=p-1;
                else x[sa[i]]=p++;
            if(p>=n) break;
        }
        for(int i=0;i<n;i++) rk[sa[i]]=i;n--;
    }
    void get_ht(){
        for(int i=0,k=0;i<n;ht[rk[i++]]=k){
            int j=sa[rk[i]-1];k=k?k-1:0;
            while(s[i+k]==s[j+k]) k++;
        }
    }
    bool check(int mid){
        int cnt=0;
        for(int i=1;i<=n;i++){
            if(ht[i]<mid) cnt=1;
            else cnt++;
            if(cnt>=K) return true;
        }
        return false;
    }
    int main(){
        while(scanf("%d%d",&n,&K)!=EOF){
            for(int i=0;i<n;i++) {
                scanf("%d",&s[i]);
                r[i].x=s[i]+1;r[i].id=i;
            }
            r[n].x=0,r[n].id=n;
            DA();get_ht();
            int l=0,r=n,ans;
            while(l<=r){
                int mid=l+r>>1;
                if(check(mid)) ans=mid,l=mid+1;
                else r=mid-1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    固定表头的table
    Object.assign()方法
    一个命令解决linux重启nginx就丢失pid文件问题
    js-xlsx 一个实用的js 导出列表插件
    SparkSQL执行时参数优化
    HSQL转化为MR过程
    简单写下提交sql-map-shuffle-reduce的过程
    order by/sort by/distribute by /cluster by 的区分
    hive中如何控制mapper的数量
    hive 窗口和分析函数功能
  • 原文地址:https://www.cnblogs.com/harden/p/6539717.html
Copyright © 2020-2023  润新知