http://www.cnblogs.com/jinkun113/p/4743694.html
https://www.luogu.org/blog/black-jokers/solution1-p3809
https://xminh.github.io/2018/02/27/%E5%90%8E%E7%BC%80%E6%95%B0%E7%BB%84-%E6%9C%80%E8%AF%A6%E7%BB%86(maybe)%E8%AE%B2%E8%A7%A3.html
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=2e6+10;
int n,m,a[maxn],buc[maxn],x[maxn],y[maxn],sa[maxn];
char s[maxn];
void radix(){
memset(buc,0,sizeof(buc));
for(int i=1;i<=n;i++) buc[x[y[i]]]++;
for(int i=2;i<=m;i++) buc[i]+=buc[i-1];
for(int i=n;i>=1;i--) sa[buc[x[y[i]]]--]=y[i];
}
void getsa(){
m=62;
for(int i=1;i<=n;i++) x[i]=a[i],y[i]=i;
radix();
for(int k=1;k<=n;k<<=1){
int p=0;
for(int i=n-k+1;i<=n;i++) y[++p]=i;
for(int i=1;i<=n;i++) if(sa[i]>k) y[++p]=sa[i]-k;
radix();
swap(x,y);
x[sa[1]]=1,p=1;
for(int i=2;i<=n;i++)
x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p;
if(p==n) break;
m=p;
}
}
int main(){
scanf("%s",s);
int len=strlen(s);
for(int i=0;i<len;i++){
if(s[i]>='0'&&s[i]<='9') a[++n]=s[i]-'0'+1;
else if(s[i]>='A'&&s[i]<='Z') a[++n]=s[i]-'A'+11;
else a[++n]=s[i]-'a'+37;
}
getsa();
for(int i=1;i<=n;i++){
if(i!=1) putchar(' ');
printf("%d",sa[i]);
}
putchar('\n');
return 0;
}