【UOJ #35】后缀排序 后缀数组模板

本文深入探讨了后缀数组的构建方法及其在字符串处理中的应用,详细讲解了基数排序算法,并提供了一个完整的C++代码实现。通过重新编写模板,强调了用于基数排序的数组必须足够大以容纳所有元素的重要性。

http://uoj.ac/problem/35
以前做后缀数组的题直接粘模板。。。现在重新写一下模板
注意用来基数排序的数组一定要开到N。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100003;

int t1[N], t2[N], c[N];

void st(int *x, int *y, int *sa, int n, int m) {
    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];
}

void mkhz(int *r, int *sa, int n, int m) {
    int *x, *y, *t, i, j, p;
    x = t1; y = t2;
    for (i = 0; i < n; ++i) x[i] = r[i], y[i] = i;
    st(x, y, sa, n, m);
    for (p = 1, j = 1; j < n && p < n; j <<= 1, m = p - 1) {
        for (p = 0, i = n - j; i < n; ++i) y[p++] = i;
        for (i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
        st(x, y, sa, n, m);
        for (t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; ++i)
            x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + j] == y[sa[i] + j] ? p - 1 : p++;
    }
}

void mkh(int *r, int *sa, int *rank, int *h, int n) {
    h[1] = 0; int k = 0, j;
    for (int i = 1; i < n; ++i) rank[sa[i]] = i;
    for (int i = 1; i < n; h[rank[i++]] = k)
        for (k ? --k : k = 0, j = sa[rank[i] - 1]; r[j + k] == r[i + k]; ++k);
}

char s[N];
int r[N], sa[N], h[N], rank[N];

int main() {
    scanf("%s", s + 1);
    int len = strlen(s + 1);
    for (int i = 1; i <= len; ++i) r[i] = s[i] - 'a' + 1;
    mkhz(r, sa, len + 1, 26);
    for (int i = 1; i <= len; ++i) printf("%d ", sa[i]);
    puts("");
    
    mkh(r, sa, rank, h, len + 1);
    for (int i = 2; i <= len; ++i) printf("%d ", h[i]);
    puts("");
    return 0;
}

转载于:https://www.cnblogs.com/abclzr/p/6171089.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值