注释挂了
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+5;
int readint(){
int x=0,f=1;char s=getchar();
#define sc (s=getchar())
while(s<'0'||s>'9'){
if(s=='-')
f=-1;
sc;
}
while(s>='0'&&s<='9'){
x=(x<<3)+(x<<1)+(s^48);
sc;
}
#undef sc
return x*f;
}
char s[maxn];
int rank[maxn],sa[maxn];//从i开始的后缀的排名,排名为i的开始位置
int x[maxn],y[maxn];//第一关键字,第二关键字,基数排序的时候用的
int cnt[maxn];//统计字符集中每个的个数
int main (){
scanf("%s",s+1);
int n=strlen(s+1);
int maxsize=150;//字符集大小
for(int i=1;i<=n;i++){//先按第一个关键字存进桶里
x[i]=s[i];
// cout<<x[i]<<endl;
cnt[x[i]]++;
}
for(int i=2;i<=maxsize;i++)//累计起来,看每个字符在所有当中哪个位置
cnt[i]+=cnt[i-1];
for(int i=n;i>=1;i--)//第一个的位置
sa[cnt[x[i]]--]=i;
for(int k=1;k<=n;k<<=1){//倍增
int num=0;
//按照第二关键字从小到大排序
for(int i=n-k+1;i<=n;i++)//后面n-k+1没有字符了
y[++num]=i;
for(int i=1;i<=n;i++)//如果某个他是大于k的,那他是可以做另外一个字符串的后k个
if(sa[i]>k)
y[++num]=sa[i]-k;
for(int i=1;i<=maxsize;i++)//清空字符集
cnt[i]=0;
for(int i=1;i<=n;i++)//直接第一关键字排序
++cnt[x[i]];
for(int i=2;i<=maxsize;i++)
cnt[i]+=cnt[i-1];
for(int i=n;i>=1;i--)
sa[cnt[x[y[i]]]--]=y[i],y[i]=0;//如果第二关键字大的,肯定在同样的第一个关键字中排后面
swap(x,y);
x[sa[1]]=1;num=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])?num:++num;
//第一个关键字和第二个关键字都相同就前缀相同了,否则就重新赋值
if(num==n)
break;
maxsize=num;
}
for(int i=1;i<=n;i++){
printf("%d ",sa[i]);
}
return 0;
}