洛谷P3809 【模板】后缀排序

初学后缀数组,还没有理解透,有时间再好好理解一下

Code:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define setIO(s) freopen(s".in","r",stdin) 
#define maxn 1000013
using namespace std;
char str[maxn];
int a[maxn],rk[maxn],sa[maxn],tp[maxn],tax[maxn],n,m;

void read(){
    scanf("%s",str);
    n=strlen(str);
    for(int i=0;i<n;++i) a[i+1]=str[i]; 
}
void qsort(){
    for(int i=0;i<=m;++i) tax[i]=0;
    for(int i=1;i<=n;++i) ++tax[rk[tp[i]]]; 
    for(int i=1;i<=m;++i) tax[i]+=tax[i-1];
    for(int i=n;i>=1;--i) sa[tax[rk[tp[i]]]--]=tp[i]; 
}
void suffix(){
    for(int i=1;i<=n;++i) rk[i]=a[i],tp[i]=i; 
    qsort(); 
    for(int k=1;k<=n;k<<=1){
        int num=0;
        for(int i=n-k+1;i<=n;++i)tp[++num]=i;
        for(int i=1;i<=n;++i) if(sa[i]>k) tp[++num]=sa[i]-k; 
        qsort();
        swap(rk,tp);
        rk[sa[1]]=1;
        num=1;
        for(int i=2;i<=n;++i) 
            rk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+k]&&tp[sa[i]+k]==tp[sa[i-1]+k])?num:++num;
        if(num==n) break;
        m=num;  
    }
    return; 
}
int main(){
    //setIO("input"); 
    read();
    m=122; 
    suffix(); 
    for(int i=1;i<=n;++i) printf("%d ",sa[i]);
    return 0; 
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/10266765.html