学了很久,算是解决了一块心病,
虽然大致能理解,但现在也只是停留在写模板的程度
存个模板先
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; const int MAXN=1e6+10; char s[MAXN]; int n,m,sa[MAXN],rk[MAXN],tp[MAXN],c[MAXN],height[MAXN]; void getsa(){ m='z'; for(int i=1;i<=n;i++) c[rk[i]=s[i]]++; for(int i=1;i<=m;i++) c[i]+=c[i-1]; for(int i=n;i>=1;i--) sa[c[rk[i]]--]=i; for(int w=1,p=0;p<n;w<<=1,m=p){ p=0; for(int i=n-w+1;i<=n;i++) tp[++p]=i; for(int i=1;i<=n;i++) if(sa[i]>w) tp[++p]=sa[i]-w; for(int i=1;i<=m;i++) c[i]=0; for(int i=1;i<=n;i++) c[rk[i]]++; for(int i=1;i<=m;i++) c[i]+=c[i-1]; for(int i=n;i>=1;i--) sa[c[rk[tp[i]]]--]=tp[i]; swap(rk,tp); rk[sa[1]]=p=1; for(int i=2;i<=n;i++) rk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+w]==tp[sa[i-1]+w])?p:++p; } } void getheight(){ int k=0; for(int i=1;i<=n;i++){ if(rk[i]==1) continue; if(k) k--; int j=sa[rk[i]-1]; while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) k++; height[rk[i]]=k; } } int main(){ scanf("%s",s+1); n=strlen(s+1); getsa(); getheight(); for(int i=1;i<=n;i++) printf("%d%c",sa[i]-1,i<n?' ':'\n'); for(int i=1;i<=n;i++) printf("%d%c",height[i],i<n?' ':'\n'); return 0; }