后缀数组
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int N=1e5+5; char s[N]; int len,maxx,sa[N],rank[N],sum[N],tsa[N],trank[N],height[N]; void Radix_sort() { maxx=256; memset(sum,0,sizeof(sum)); for(int i=1;i<=len;i++) { rank[i]=s[i]; sum[rank[i]]++; } for(int i=2;i<=maxx;i++) sum[i]+=sum[i-1]; for(int i=len;i;i--) sa[sum[rank[i]]--]=i; } void DA() { int p; Radix_sort(); trank[sa[1]]=1,p=1; for(int i=2;i<=len;i++) { if(rank[sa[i]]!=rank[sa[i-1]]) p++; trank[sa[i]]=p; } for(int i=1;i<=len;i++) rank[i]=trank[i]; for(int j=1;p<len;j<<=1,maxx=p) { p=0; for(int i=len-j+1;i<=len;i++) tsa[++p]=i; for(int i=1;i<=len;i++) if(sa[i]>j) tsa[++p]=sa[i]-j; memset(sum,0,sizeof(sum)); for(int i=1;i<=len;i++) trank[i]=rank[tsa[i]]; for(int i=1;i<=len;i++) sum[trank[i]]++; for(int i=2;i<=maxx;i++) sum[i]+=sum[i-1]; for(int i=len;i;i--) sa[sum[trank[i]]--]=tsa[i]; trank[sa[1]]=1,p=1; for(int i=2;i<=len;i++) { if((rank[sa[i]]!=rank[sa[i-1]])||(rank[sa[i]+j]!=rank[sa[i-1]+j])) p++; trank[sa[i]]=p; } for(int i=1;i<=len;i++) rank[i]=trank[i]; } for(int i=1,k=0;i<=len;i++) { int j=sa[rank[i]-1]; while(s[i+k]==s[j+k]) k++; height[rank[i]]=k; if(k>0) k--; } } int main() { scanf("%s",s+1); len=strlen(s+1); DA(); for(int i=1;i<=len;i++) printf("%d ",sa[i]); printf("\n"); for(int i=2;i<=len;i++) printf("%d ",height[i]); }