以 luogu P3809 为例
#include <cstdio>
#include <cstring>
#define R register
const int MaxN = 1000010;
int SA[MaxN], Rank[MaxN], Height[MaxN], x[MaxN], sum[MaxN], y[MaxN];
char s[MaxN];
bool cmp(R int i, R int j, R int k){ return x[i] == x[j] && x[i + k] == x[j + k]; }
int main()
{
scanf("%s", s + 1);
R int n = strlen(s + 1), m = 128;
for(R int i = 1; i <= n; i++) sum[x[i] = s[i]]++;
for(R int i = 1; i <= m; i++) sum[i] += sum[i - 1];
for(R int i = n; i; i--) SA[sum[x[i]]--] = i;
for(R int i = 1; i < n; i <<= 1)
{
R int pos = 0; //此时的y是用于计算SA数组的
for(R int j = n - i + 1; j <= n; j++) y[++pos] = j; //将长度小于2^i的后缀的第二关键字为0,肯定排在前头,而且按照从前往后的顺序
for(R int j = 1; j <= n; j++) if(SA[j] > i) y[++pos] = SA[j] - i; //这一步其实把第二关键字非0的都加入了,SA[j]<=i的数都排在前i个,一定不会作为其他数的第二关键字
for(R int j = 1; j <= m; j++) sum[j] = 0;
for(R int j = 1; j <= n; j++) sum[x[j]]++;
for(R int j = 1; j <= m; j++) sum[j] += sum[j - 1];
for(R int j = n; j; j--) SA[sum[x[y[j]]]--] = y[j]; //根据第二关键字给出的顺序,进行第一关键字的排序
y[SA[1]] = 1; //此时的y是用于计算x数组的,与前面的用途没有任何关系
for(R int j = 2; j <= n; j++) y[SA[j]] = y[SA[j - 1]] + !cmp(SA[j], SA[j - 1], i);
for(R int j = 1; j <= n; x[j] = y[j], j++);
m = x[SA[n]];
if(m == n) break;
}
for(R int i = 1; i <= n; i++) printf("%d ", SA[i]);
return 0;
}