二次联通门 : luogu P3809 【模板】后缀排序
LibreOJ : LibreOJ #111. 后缀排序
/* luogu P3809 【模板】后缀排序 后缀数组 sa表示 排名为i的是第几个后缀 求出sa数组后输出即可 */ #include <cstdio> #include <cstring> #define Max 1000008 void read (int &now) { register char word = getchar (); for (now = 0; word < '0' || word > '9'; word = getchar ()); for (; word >= '0' && word <= '9'; now = now * 10 + word - '0'); } inline void Swap (int *&a, int *&b) { int *now = a; a = b; b = now; } int sa[Max], rank[Max]; int height[Max]; char line[Max]; int str_1[Max], str_2[Max]; int N, M; void Get_Suffix () { register int i; static int c[Max], *x = str_1, *y = str_2; for (i = 0; i < M; c[i ++] = 0); for (i = 0; i < N; c[x[i] = line[i]] ++, i ++); for (i = 1; i < M; c[i] += c[i - 1], i ++); for (i = N - 1; i >= 0; sa[-- c[x[i]]] = i --); register int pos; pos = 1; for (int j = 1; pos < N; j <<= 1, M = pos) { pos = 0; for (i = N - j; i < N; y[pos ++] = i ++); for (i = 0; i < N; i ++) if (sa[i] >= j) y[pos ++] = sa[i] - j; for (i = 0; i < M; c[i ++] = 0); for (i = 0; i < N; c[x[y[i]]] ++, i ++); for (i = 0; i < M; c[i] += c[i - 1], i ++); for (i = N - 1; i >= 0; sa[-- c[x[y[i]]]] = y[i --]); Swap (x, y); pos = 1; x[sa[0]] = 0; for (i = 1; i < N; i ++) x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + j] == y[sa[i] + j] ? pos - 1 : pos ++; } } int main (int argc, char *argv[]) { scanf ("%s", line); N = strlen (line); M = 200; Get_Suffix (); for (int i = 0; i < N; i ++) printf ("%d ", sa[i] + 1); return 0; }