后缀数组

#include<bits/stdc++.h>
using namespace std;
#define N 1000005
int n,j,b[N],rk[N],tmp[N],sa[N],s[N],maxn,h[N];
char a[N];
void pai(){
    memset(s,0,sizeof(s));
    for(int i=1;i<=n;i++) s[rk[b[i]]]++,maxn=max(maxn,rk[b[i]]);
    for(int i=1;i<=maxn;i++) s[i]+=s[i-1];
    for(int i=n;i>=1;i--) sa[s[rk[b[i]]]--]=b[i];
}
int tong(int x,int y){
    if(rk[x]==rk[y]&&rk[x+j]==rk[y+j]) return 1;
    return 0;
}
void get_sa(){
    for(int i=1;i<=n;i++) rk[i]=a[i]-'0'+1,b[i]=i;
    pai();
    for(j=1;j<n;j*=2){
        int tot=0,cnt=0;
        for(int i=n-j+1;i<=n;i++) b[++tot]=i;
        for(int i=1;i<=n;i++){
            if(sa[i]>j) b[++tot]=sa[i]-j;
        }
        pai();
        for(int i=1;i<=n;i++){
            if(tong(sa[i],sa[i-1])) tmp[sa[i]]=cnt;
            else tmp[sa[i]]=++cnt;
        }
        memcpy(rk,tmp,sizeof(tmp));
    }
}
void get_h(){
    for(int i=1;i<=n;i++){
        if(rk[i]==1) h[i]=0;
        else{
            int k=max(h[i-1]-1,0ll);
            while(i+k<=n&&sa[rk[i]-1]+k<=n&&a[i+k]==a[sa[rk[i]-1]+k]) k++;
            h[i]=k;
        }
    }
}
int main(){
    scanf("%s",a+1);
    n=strlen(a+1);
    get_sa();
    get_h();
    for(int i=1;i<=n;i++) printf("%d ",sa[i]);
    return 0;
}
posted @ 2022-08-08 17:14  hubingshan  阅读(21)  评论(0)    收藏  举报  来源