uoj35: 后缀排序

来源:互联网 发布:mysql nosql 编辑:程序博客网 时间:2024/06/06 02:18

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

#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;}
0 0
原创粉丝点击