uoj35: 后缀排序

原创 2017年01月03日 10:55:32

题目链接
后缀数组模板题。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 100010;

int n, c[N], sa[N];
int rank[N], height[N];
char str[N];

inline void buildSa(int m) {
    int *x = rank, *y = height;
    for (int i = 0; i < m; i++) c[i] = 0;
    for (int i = 0; i < n; i++) c[x[i] = str[i]]++;
    for (int i = 1; i < m; i++) c[i] += c[i - 1];
    for (int i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
    for (int k = 1; k <= n; k <<= 1) {
        int 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 >= 0; i--) sa[--c[x[y[i]]]] = y[i];
        swap(x, y); x[sa[0]] = 0; p = 1;
        for (int i = 1; i < n; i++)
            x[sa[i]] = y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k] ? p - 1 : p++;//这里有点担心越界
        if (p >= n) break;
        m = p;
    }
}
inline void calcHeight() {
    int k = 0;
    for (int i = 0; i < n; i++) rank[sa[i]] = i;
    for (int i = 0; i < n - 1; i++) {
        if (k) k--;
        int j = sa[rank[i] - 1];
        while (str[i + k] == str[j + k]) k++;
        height[rank[i]] = k;
    }
}

int main() {
    scanf("%s", str);
    n = strlen(str);
    for (int i = 0; i < n; i++)
        str[i] -= 'a' - 1;
    str[n++] = 0;//补$不能省略
    buildSa(30);
    calcHeight();
    for (int i = 1; i < n; i++)
        printf("%d ", sa[i] + 1); puts("");
    for (int i = 2; i < n; i++)
        printf("%d ", height[i]); puts("");
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

[UOJ35]后缀排序

后缀自动机 后缀树 后缀数组
  • hbhcy98
  • hbhcy98
  • 2016年04月07日 19:16
  • 269

UOJ35 后缀排序 后缀数组

大家都很强, 可与之共勉 。清嗓子,之前的后缀数组的板子都有问题……  特此补一个# include # define N 100010class Suffix_Array { private : ...
  • simpsonk
  • simpsonk
  • 2017年12月12日 11:21
  • 81

【uoj35】后缀排序

这是一道模板题。读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置。位置编号为 1 到 n。除此之外为了进...
  • w_yqts
  • w_yqts
  • 2017年05月19日 17:37
  • 114

[UOJ35]后缀排序 做题笔记

题目链接:http://uoj.ac/problem/35 这也是个后缀数组的模板题。。。#include #include #include using namespace std; con...
  • mhlwsk
  • mhlwsk
  • 2016年03月14日 17:03
  • 231

UOJ #35 后缀排序(后缀数组)

题目链接 题解:后缀数组板子 之前学后缀数组只是学了个大概,而且写的是二维的。现在从头理一遍,改成了算法导论上的写法。。 #include #include #include #include #...
  • clover_hxy
  • clover_hxy
  • 2016年12月28日 10:54
  • 468

后缀排序 后缀自动机的应用

同步个人博客 http://sxysxy.org/blogs/23 到csdn)给一字符串的所有后缀排个序输出,字符串长度 ...
  • u013632138
  • u013632138
  • 2016年08月31日 13:57
  • 865

后缀子串排序

题目描述: 对于一个字符串,将其后缀子串进行排序,例如grain 其子串有: grain rain ain in n 然后对各子串按字典顺序排序,即: ain,grain,...
  • u010112493
  • u010112493
  • 2016年02月08日 22:51
  • 762

Codevs_P1500 后缀排序(后缀数组+基数排序)

Codevs传送门时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master题目描述 Description 天凯是MIT的新生。Prof. HandsomeG给了他一...
  • qq_18455665
  • qq_18455665
  • 2016年03月29日 19:08
  • 551

linux按照文件后缀进行排序

服务器上面有很多文件,xxx.1,xxx2.1,xxxx3.1,yyy.2,yyy2.2yyy3.2,zzz.3,zzz2.3类似这样的,现在想安装文件的后缀对该文件进行排序,需要查看sort命令。 ...
  • lirenzuo
  • lirenzuo
  • 2017年04月12日 13:57
  • 3752

CodeVS1500 后缀排序

CodeVS1500 后缀排序 题目描述 Description 天凯是MIT的新生。Prof. HandsomeG给了他一个长度为n的由小写字母构成的字符串,要求他把该字符串的n...
  • FSAHFGSADHSAKNDAS
  • FSAHFGSADHSAKNDAS
  • 2016年09月25日 14:12
  • 234
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:uoj35: 后缀排序
举报原因:
原因补充:

(最多只允许输入30个字)