洛谷P3809 【模板】后缀排序

【模板】后缀排序

题目传送门

代码如下

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

inline int read(){
    int res = 0, w = 0; char ch = 0;
    while(!isdigit(ch)){
        w |= ch == '-', ch = getchar();
    }
    while(isdigit(ch)){
        res = (res << 3) + (res << 1) + (ch ^ 48);
        ch = getchar();
    }
    return w ? -res : res;
}

const int N = 1000005;

char s[N];
int sa[N], x[N], y[N], c[N];
int n, m;

void get_sa()
{
    for(int i = 1; i <= m; i ++) c[i] = 0;
    for(int i = 1; i <= n; i ++) c[x[i] = s[i]] ++;
    for(int i = 1; i <= m; i ++) c[i] += c[i - 1];
    for(int i = n; i >= 1; i --) sa[c[x[i]] --] = i;
    for(int k = 1; k <= n; k <<= 1){
        int num = 0;
        for(int i = n - k + 1; i <= n; i ++) y[++num] = i;
        for(int i = 1; i <= n; i ++) if(sa[i] > k) y[++num] = sa[i] - k;
        for(int i = 1; i <= m; i ++) c[i] = 0;
        for(int i = 1; i <= n; i ++) c[x[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], y[i] = 0;
        swap(x, y);
        num = 1;
        x[sa[1]] = num;
        for(int i = 2; i <= n; i ++)
            if(sa[i] + k <= n && sa[i - 1] + k <= n)
                x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k])? num: ++num;
            else
                x[sa[i]] = ++num;
        if(num == n)
            break;
        m = num;
    }
    for(int i = 1; i <= n; i ++){
        if(i != 1)
            putchar(' ');
        printf("%d", sa[i]);
    }
    putchar('\n');
}

int main()
{
    gets(s + 1);
    n = strlen(s + 1);
    m = 'z';
    get_sa();
    return 0;
}
posted @ 2019-08-27 19:39  whisperlzw  阅读(115)  评论(0编辑  收藏  举报