1+ #include < bits/stdc++.h>
2+ using namespace std ;
3+ typedef long long ll;
4+ #define mn 1000010
5+ char s[mn];
6+ ll n, sa[mn], rk[mn], oldrk[mn << 1 ], id[mn], px[mn], cnt[mn];
7+ bool cmp (ll x, ll y, ll w)
8+ {
9+ return oldrk[x] == oldrk[y] && oldrk[x + w] == oldrk[y + w];
10+ }
11+ ll m = 300 , i, p, w; // ASCII范围<300为计数排序值域,p是新值域
12+ signed main ()
13+ {
14+ scanf (" %s" , s + 1 ), n = strlen (s + 1 );
15+ for (ll i = 1 ; i <= n; ++i)
16+ { // 暂时以第一关键字为排序值,有很多同名并列
17+ ++cnt[rk[i] = s[i]];
18+ }
19+ for (ll i = 1 ; i <= m; ++i)
20+ {
21+ cnt[i] += cnt[i - 1 ];
22+ }
23+ for (ll i = n; i >= 1 ; --i)
24+ {
25+ sa[cnt[rk[i]]--] = i;
26+ }
27+ for (w = 1 ;; w <<= 1 , m = p)
28+ {
29+ for (p = 0 , i = n; i > n - w; --i)
30+ { // 第二关键字排序;无穷小区域
31+ id[++p] = i;
32+ }
33+ for (ll i = 1 ; i <= n; ++i)
34+ {
35+ if (sa[i] > w)
36+ {
37+ id[++p] = sa[i] - w;
38+ }
39+ }
40+ memset (cnt, 0 , sizeof cnt);
41+ for (ll i = 1 ; i <= n; ++i) // 第一关键字排序
42+ {
43+ ++cnt[px[i] = rk[id[i]]];
44+ }
45+ for (ll i = 1 ; i <= m; ++i)
46+ {
47+ cnt[i] += cnt[i - 1 ];
48+ }
49+ for (ll i = n; i >= 1 ; --i)
50+ {
51+ sa[cnt[px[i]]--] = id[i];
52+ }
53+ memcpy (oldrk, rk, sizeof rk);
54+ for (p = 0 , i = 1 ; i <= n; ++i)
55+ {
56+ rk[sa[i]] = cmp (sa[i], sa[i - 1 ], w) ? p : ++p;
57+ }
58+ if (p == n)
59+ {
60+ for (ll i = 1 ; i <= n; ++i)
61+ {
62+ sa[rk[i]] = i;
63+ }
64+ break ;
65+ }
66+ }
67+ for (ll i = 1 ; i <= n; ++i)
68+ {
69+ printf (" %lld " , sa[i]);
70+ }
71+ return 0 ;
72+ }
0 commit comments