[洛谷P3809]【模板】后缀排序

[洛谷P3809]【模板】后缀排序

题目大意:

对于给定的长度为\(n(n\le10^6)\)的字符串求后缀数组\(sa[i]\)

思路:

倍增+快排构造后缀数组。代码参考《挑战程序设计竞赛》。时间复杂度\(\mathcal O(n\log^2n)\)

源代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=1e6+1;
char s[N];
int n,k,sa[N],rank[N],tmp[N];
inline bool cmp(const int &i,const int &j) {
    if(rank[i]!=rank[j]) return rank[i]<rank[j];
    const int ri=i+k<=n?rank[i+k]:-1;
    const int rj=j+k<=n?rank[j+k]:-1;
    return ri<rj;
}
inline void suffix_sort() {
    for(register int i=0;i<=n;i++) {
        sa[i]=i;
        rank[i]=i<n?s[i]:-1;
    }
    for(k=1;k<=n;k<<=1) {
        std::sort(&sa[0],&sa[n]+1,cmp);
        tmp[sa[0]]=0;
        for(register int i=1;i<=n;i++) {
            tmp[sa[i]]=tmp[sa[i-1]]+!!cmp(sa[i-1],sa[i]);
        }
        for(register int i=0;i<=n;i++) {
            rank[i]=tmp[i];
        }
    }
    
}
int main() {
    scanf("%s",s);
    n=strlen(s);
    suffix_sort();
    for(register int i=1;i<=n;i++) {
        printf("%d%c",sa[i]+1," \n"[i==n]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/skylee03/p/9171313.html