zoukankan      html  css  js  c++  java
  • uoj35 后缀排序

    题目链接:http://uoj.ac/problem/35

    这是一道模板题。

    读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置。位置编号为 1n

    除此之外为了进一步证明你确实有给后缀排序的超能力,请另外输出 n1 个整数分别表示排序后相邻后缀的最长公共前缀的长度。

    输入格式

    一行一个长度为 n 的仅包含小写英文字母的字符串。

    输出格式

    第一行 n 个整数,第 i 个整数表示排名为 i 的后缀的第一个字符在原串中的位置。

    第二行 n1个整数,第 i 个整数表示排名为 i 和排名为 i+1 的后缀的最长公共前缀的长度。

    样例一

    input

    ababa

    output

    5 3 1 4 2
    1 3 0 2

    explanation

    排序后结果为:

    1. a
    2. aba
    3. ababa
    4. ba
    5. baba

    限制与约定

    1n10^5

    时间限制1s

    空间限制256MB

    感想:

    对uoj非常的资瓷啊,后缀数组裸题,不懂的自行百度

    献上一个大爷的博客链接:http://blog.csdn.net/shiqi_614/article/details/7982915

    代码

    #include <cstdio>
    #include <cstring>
    using namespace std;
    int i,j,k,n,m,x,y,t,a[200010],b[100010],b1[100010],d[100010],rk[100010],p[100010],h[100010],s1[100010];
    int height[100010],ans1[100010];
    char s[100010];
    struct data{int x,y;}c[100010],e[100010];
    void get_sa(){
        for (i=1;i<=n;i++)b[s[i]-'a']=1;
        for (i=1;i<26;i++)b[i]+=b[i-1];
        for (i=1;i<=n;i++)a[i]=b[s[i]-'a'];
        for (k=1;k<=n;k*=2){
            for (i=1;i<=n;i++)c[i].x=a[i],c[i].y=a[i+k];
            memset(b,0,sizeof b);
            for (i=1;i<=n;i++)b[c[i].y]++;
            for (i=1;i<=n;i++)b[i]+=b[i-1];
            for (i=1;i<=n;i++)d[b[c[i].y]]=i,b[c[i].y]--;
            for (i=1;i<=n;i++)e[i]=c[d[i]];
            for (i=1;i<=n;i++)c[i]=e[i];
            for (i=1;i<=n;i++)p[i]=d[i];
            memset(b,0,sizeof b);
            for (i=1;i<=n;i++)b[c[i].x]++;
            for (i=1;i<=n;i++)b[i]+=b[i-1];
            for (i=n;i>=1;i--)d[b[c[i].x]]=i,b[c[i].x]--;
            for (i=1;i<=n;i++)e[i]=c[d[i]],rk[i]=d[i];
            for (i=1;i<=n;i++)c[i]=e[i];
            s1[1]=1;
            for (i=2;i<=n;i++)if (c[i].x!=c[i-1].x||c[i].y!=c[i-1].y)s1[i]=s1[i-1]+1;else s1[i]=s1[i-1];
            for (i=1;i<=n;i++)a[p[rk[i]]]=s1[i];
        }
        for (i=1;i<=n;i++)rk[a[i]]=i;
        for (i=1;i<=n;i++)printf("%d ",rk[i]);printf("
    ");
    }
    void get_h(){
        int k=0;
        for (int i=1;i<=n;i++){
            if (a[i]==1) h[i]=k=0;
            else{
                j=rk[a[i]-1];
                if (k>0) k--;
                while (i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) k++;
                h[i]=k;
            }
            height[a[i]]=h[i];
        }
        for (int i=2; i<=n; i++) printf("%d ",height[i]);
    }
    int main(){
        gets(s);
        n=strlen(s);
        for (i=n;i>=1;i--)s[i]=s[i-1];
        get_sa();
        get_h();
        return 0;
    }
  • 相关阅读:
    Hadoop跳过回收站删除HDFS文件
    hadoop安全模式解除方法和为什么会安全模式
    从业18年,我总结了9个最有价值的经验
    mysql复制整个数据库及数据
    Oozie调度原理(queueName与launcher_queName详解)
    Hive升级参考
    Hive表设计压缩问题
    sql中join的on和where操作引发的谓词下推优化
    将毫秒转换成天小时分钟
    数据库优化之一:通过修改postgresql的Planner Method Configuration更改 查询计划优化慢sql
  • 原文地址:https://www.cnblogs.com/Acheing/p/6786455.html
Copyright © 2011-2022 走看看