[板子]后缀数组
1 #include<bits/stdc++.h> 2 #define N 10000010*2 3 using namespace std; 4 char s[N]; 5 int n; 6 int sa[N],rk[N],height[N],t1[N],t2[N],c[N]; 7 int a[N]; 8 void get_sa(int n,int m){ 9 int *x=t1,*y=t2; 10 for(int i=1;i<=m;++i)c[i]=0; 11 for(int i=1;i<=n;++i)c[x[i]=a[i]]++; 12 for(int i=1;i<=m;++i)c[i]+=c[i-1]; 13 for(int i=n;i>=1;--i)sa[c[x[i]]--]=i; 14 for(int k=1;k<=n;k<<=1){ 15 int p=0; 16 for(int i=n-k+1;i<=n;++i)y[++p]=i; 17 for(int i=1;i<=n;++i)if(sa[i]>k)y[++p]=sa[i]-k; 18 for(int i=1;i<=m;++i)c[i]=0; 19 for(int i=1;i<=n;++i)c[x[y[i]]]++; 20 for(int i=1;i<=m;++i)c[i]+=c[i-1]; 21 for(int i=n;i>=1;--i)sa[c[x[y[i]]]--]=y[i]; 22 swap(x,y); 23 p=1;x[sa[1]]=1; 24 for(int i=2;i<=n;++i) 25 x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p:++p; 26 if(p==n)break; 27 m=p; 28 } 29 for(int i=1;i<=n;++i)rk[sa[i]]=i; 30 int f=0; 31 for(int i=1;i<=n;++i){ 32 int j=sa[rk[i]-1]; 33 if(f)f--; 34 while(i+f<=n&&j+f<=n&&s[j+f]==s[i+f])f++; 35 height[rk[i]]=f; 36 } 37 } 38 int main(){ 39 scanf("%s",s+1);n=strlen(s+1); 40 for(int i=1;i<=n;++i)a[i]=s[i]; 41 get_sa(n,150); 42 for(int i=1;i<=n;++i) 43 printf("%d%c",sa[i],i==n?'\n':' '); 44 return 0; 45 }
Keep it simple and stupid.