zoukankan      html  css  js  c++  java
  • SPOJ 7258 SUBLEX 后缀数组 + 二分答案 + 前缀和

    Code:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define setIO(s) freopen(s".in","r",stdin)
    #define maxn 1000000
    #define ll long long
    using namespace std;
    char str[maxn];
    int arr[maxn],pos[maxn],x[maxn],rk[maxn],sa[maxn],c[maxn],height[maxn]; 
    ll C[maxn],brr[maxn]; 
    int n,m;
    struct SA{
        void qsort(){
            for(int i=0;i<=m;++i) c[i]=0;
            for(int i=1;i<=n;++i) ++c[rk[pos[i]]];
            for(int i=1;i<=m;++i) c[i]+=c[i-1];
            for(int i=n;i>=1;--i) sa[c[rk[pos[i]]]--]=pos[i]; 
        }
        void build(){
            for(int i=1;i<=n;++i) rk[i]=arr[i],pos[i]=i; 
            qsort();
            for(int k=1;k<=n;k<<=1){
                int num=0;
                for(int i=n-k+1;i<=n;++i) pos[++num]=i;
                for(int i=1;i<=n;++i) if(sa[i]>k) pos[++num]=sa[i]-k; 
                qsort();
                swap(rk,pos);
                rk[sa[1]]=1,num=1;
                for(int i=2;i<=n;++i)
                    rk[sa[i]]=(pos[sa[i]]==pos[sa[i-1]]&&pos[sa[i]+k]==pos[sa[i-1]+k])?num:++num;
                if(num==n) break;
                m=num; 
            }
        }
        void get_height(){
            int k=1;
            for(int i=1;i<=n;++i) rk[sa[i]]=i; 
            for(int i=1;i<=n;++i){
                if(k) --k;
                int j=sa[rk[i]-1];
                while(arr[i+k]==arr[j+k]) ++k;
                height[rk[i]]=k;  
            }
        }
    }T;
    int main(){
        //setIO("input"); 
        scanf("%s",str),n=strlen(str),m=128;
        for(int i=1;i<=n;++i) arr[i]=str[i-1]; 
        T.build(),T.get_height(); 
        for(int i=1;i<=n;++i) brr[i]=n-sa[i]+1-height[i];
        for(int i=1;i<=n;++i) C[i]=C[i-1]+brr[i];
        int q; long long opt;  scanf("%d",&q);
        while(q--){
            scanf("%lld",&opt);
            int l=1,r=n,mid,ans=0; 
            while(l<=r) {
                mid=(l+r)>>1;
                if(C[mid]>=opt) ans=mid,r=mid-1;
                else l=mid+1;
            }
            for(int i=sa[ans];i<=n-(C[ans]-opt);++i) printf("%c",str[i-1]);  
            printf("
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    树的最小支配集 最小点覆盖 与 最大独立集 (图论)
    P1993 小K的农场 (差分约束)
    P1168 中位数 (优先队列,巧解)
    STL 优先队列
    P3799 妖梦拼木棒 (组合数学)
    P2389 电脑班的裁员 (动态规划)
    3-Java中基本数据类型的存储方式和相关内存的处理方式(java程序员必读经典)
    1-匿名对象
    2-封装性
    2-递归调用
  • 原文地址:https://www.cnblogs.com/guangheli/p/10279932.html
Copyright © 2011-2022 走看看