洛谷 P3809 【模板】后缀排序

题意

后缀数组板子题

传送门

Code

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1e6+10;

int n;
char str[maxn];
struct SuffixArray {
    int x[maxn], y[maxn], c[maxn];
    int sa[maxn], rk[maxn], height[maxn];

    void SA() {
        int m = 127;
        for (int i=0; i<=m; ++i) c[i] = 0;
        for (int i=1; i<=n; ++i) ++c[x[i]=str[i]];
        for (int i=1; i<=m; ++i) c[i] += c[i-1];
        for (int i=n; i; --i) sa[c[x[i]]--] = i;

        for (int p, k=1; k<=n; k<<=1) {
            p = 0;
            for (int i=n; i>n-k; --i) y[++p] = i;
            for (int i=1; 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=1; i<=n; ++i) ++c[x[y[i]]];
            for (int i=1; i<=m; ++i) c[i] += c[i-1];
            for (int i=n; i>=1; --i) sa[c[x[y[i]]]--] = y[i];

            p = y[sa[1]] = 1;
            for (int a, b, i=2; i<=n; ++i) {
                a = sa[i]+k>n?-1: x[sa[i]+k];
                b = sa[i-1]+k>n? -1: x[sa[i-1]+k];
                y[sa[i]] = (x[sa[i]]==x[sa[i-1]] && a==b)? p: ++p;
            }
            swap(x, y);
            if(p>=n) break;
            m = p;
        }
    }
    void Height() {
        int k = 0;
        for (int i=1; i<=n; ++i) {
            if(k) --k;
            int j = sa[rk[i]-1];
            while(str[i+k] == str[j+k]) ++k;
            height[i] = k;
        }
    }
}sa;

int main() {
    scanf("%s", str+1);
    n = strlen(str+1);
    sa.SA();
    for (int i=1; i<=n; ++i) printf("%d ", sa.sa[i]); puts("");
    return 0;
}

原文地址:https://www.cnblogs.com/acerkoo/p/11406355.html