zoukankan      html  css  js  c++  java
  • GDOI2012 字符串

    Description

    mmm正在学习字典序。现在老师给她布置了一个作业:给出一个字符串,问该字符串的所有不同的子串中,按字典序排第K的字串。由于众所周知的原因,mmm需要你为她解决这个问题。

     

    Input

    第1行输入一个只有小写字母组成的字符串。


    第2行输入N,为询问个数。


    第3到N+2行每行输入一个整数Ki。


    Output

    输出N行,第i行输出按字典序排第Ki的子串,如果Ki超出了子串数量,输出-1.

     

    Sample Input

    abbb
    8
    1
    2
    3
    4
    5
    6
    7
    8

    Sample Output

    a
    ab
    abb
    abbb
    b
    bb
    bbb
    -1
     

    Data Constraint

     
     

    Hint

    数据范围


    1,对于30%的数据,字符串长度≤100


    2,对于60%的数据,字符串长度≤3000


    3,对于100%的数据,字符串长度≤20000


    4,对于100%的数据,1≤N≤10

    类似于求一个字符串中不同的子串数,直接上sa即可

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    
    using namespace std;
    
    char s[20011];
    char c;
    int a[20011],b[20011],sa[20011],co[20011];
    int rank[20011],h[20011],nr[20011];
    int i,x,j,k,l,n,m;
    bool p;
    int ans[111][3];
    
    struct data{
        int x,idx;
    }q[111];
    
    bool cmp(data a,data b)
    {
        return a.x<b.x;
    }
    
    void Read()
    {
        while(c=getchar(),c<'a'||c>'z');
        s[++n]=c;
        while(c=getchar(),c>='a'&&c<='z')s[++n]=c;
    }
    
    void sort(int *a)
    {
        int i,mn;
        if(27>n)mn=27;
        else mn=n;
        for(i=0;i<=mn;i++)co[i]=0;
        for(i=1;i<=n;i++)co[a[i]+1]++;
        for(i=1;i<=mn;i++)co[i]+=co[i-1];
        for(i=1;i<=n;i++)nr[i]=0;
        for(i=1;i<=n;i++){
            co[a[sa[i]]]++;
            nr[co[a[sa[i]]]]=sa[i];
        }
        for(i=1;i<=n;i++)sa[i]=nr[i];
    }
    
    void getrank()
    {
        int i;
        x=0;
        for(i=1;i<=n;i++){
            if(i==1||a[sa[i]]!=a[sa[i-1]]||b[sa[i]]!=b[sa[i-1]])x++;
            rank[sa[i]]=x;
        }
    }
    
    void Suffix()
    {
        int i,j,k,last,l;
        for(i=1;i<=n;i++){
            sa[i]=i;
            a[i]=s[i]-96;
            b[i]=0;
        }
        sort(a);
        getrank();
        l=1;
        while(x!=n){
            for(i=1;i<=n;i++){
                a[i]=rank[i];
                if(i+l<=n)b[i]=rank[i+l];
                else b[i]=0;
            }
            sort(b);
            sort(a);
            getrank();
            l*=2;
        }
        last=0;
        for(i=1;i<=n;i++){
            if(last)last--;
            if(rank[i]==1)continue;
            j=i;
            k=sa[rank[i]-1];
            while(j+last<=n&&k+last<=n&&s[j+last]==s[k+last])last++;
            h[rank[i]]=last;
        }
    }
    
    int main()
    {
        Read();
        Suffix();
        scanf("%d",&m);
        for(i=1;i<=m;i++){
            scanf("%d",&q[i].x);
            q[i].idx=i;
        }
        sort(q+1,q+1+m,cmp);
        l=0;
        k=1;
        p=true;
        for(i=1;i<=m;i++){
            while(k<=n&&l+n-sa[k]+1-h[k]<q[i].x){
                l=l+n-sa[k]+1-h[k];
                k++;
            }
            if(k>n)p=false;
            if(p==false)break;
            ans[q[i].idx][1]=sa[k];
            ans[q[i].idx][2]=sa[k]+h[k]+q[i].x-l-1;
        }
        for(j=i;j<=m;j++){
            ans[q[i].idx][1]=-1;
        }
        for(i=1;i<=m;i++){
            if(ans[i][1]==-1)printf("-1
    ");
            else{
                for(j=ans[i][1];j<=ans[i][2];j++)printf("%c",s[j]);
                printf("
    ");
            }
        }
    }
  • 相关阅读:
    disruptor架构三 使用场景 使用WorkHandler和BatchEventProcessor辅助创建消费者
    disruptor架构二
    disruptor架构一
    线程池基础二
    线程池基础一
    多线程集成设计模式--MasterWorker模式讲解(一)
    多线程集成设计模式--future模式
    线程基础9-quene讲解
    线程基础8-quene讲解
    hdu3613 Best Reward
  • 原文地址:https://www.cnblogs.com/applejxt/p/3865582.html
Copyright © 2011-2022 走看看