11#include < bits/stdc++.h>
22
3- #define REP (i, n ) for (int i = 0 ; i < int (n); ++i)
4- #define REP2 (i, ini, fim ) for (int i = int (ini); i <= int (fim); ++i)
5-
63using namespace std ;
74
8- const int maxn = 101010 ;
9-
10- namespace sarray
11- {
12- string s;
13- int n, gap;
14- int sa[maxn], pos[maxn], tmp[maxn], lcp[maxn];
15-
16- bool suf_comp (int i, int j)
17- {
18- if (pos[i] != pos[j]) return pos[i] < pos[j];
19-
20- i += gap, j += gap;
21-
22- return (i < n and j < n)? pos[i] < pos[j] : i > j;
23- }
24-
25- void build ()
26- {
27- n = s.size ();
28-
29- REP (i, n) sa[i] = i, pos[i] = s[i];
30-
31- for (gap=1 ;; gap <<= 1 ) {
32-
33- sort (sa, sa+n, suf_comp);
34-
35- REP (i, n-1 ) tmp[i+1 ] = tmp[i] + suf_comp (sa[i], sa[i+1 ]);
36- REP (i, n) pos[sa[i]] = tmp[i];
37-
38- if (tmp[n-1 ] == n-1 ) break ;
39- }
40- }
41-
42- void buildLCP ()
43- {
44- for (int i = 0 , k = 0 ; i < n; ++i) if (pos[i] != n - 1 )
45- {
46- for (int j = sa[pos[i] + 1 ]; s[i + k] == s[j + k]; ++k);
47- lcp[pos[i]] = k;
48- if (k)--k;
49- }
50- }
51-
52- int ds ()
53- {
54- int result = n - sa[0 ];
55-
56- for (int i = 1 ; i < n; i++)
57- result += (n - sa[i]) - lcp[i - 1 ];
58-
59- result++;
60- return result;
61- }
62- } // namespace sarray
63-
64- int main ()
65- {
66- ios_base::sync_with_stdio (false );
67- cin.tie (0 );
68-
69- // int t;
70- // cin >> t;
71-
72- // while (t--) {
5+ vector<int > sort_cyclic_shifts (string const & s) {
6+ int const n = s.size ();
7+ int const alphabet = 256 ;
8+ vector<int > p (n), c (n), cnt (max (alphabet, n), 0 );
9+
10+ for (int i = 0 ; i < n; i++)
11+ cnt[s[i]]++;
12+ for (int i = 1 ; i < alphabet; i++)
13+ cnt[i] += cnt[i-1 ];
14+ for (int i = 0 ; i < n; i++)
15+ p[--cnt[s[i]]] = i;
16+
17+ c[p[0 ]] = 0 ;
18+ int classes = 1 ;
19+
20+ for (int i = 1 ; i < n; i++) {
21+ if (s[p[i]] != s[p[i-1 ]])
22+ classes++;
23+ c[p[i]] = classes - 1 ;
24+ }
7325
74- cin >> sarray::s;
75-
76- sarray::build ();
77- sarray::buildLCP ();
78- REP (i, sarray::n) cout << sarray::lcp[i] << " " ;
79- cout << " \n " ;
80- // sarray::buildLCP();
81-
82- // cout << sarray::ds() << "\n";
83- // }
26+ vector<int > pn (n), cn (n);
27+
28+ for (int h = 0 ; (1 << h) < n; ++h) {
29+ for (int i = 0 ; i < n; i++) {
30+ pn[i] = p[i] - (1 << h);
31+ if (pn[i] < 0 )
32+ pn[i] += n;
33+ }
34+
35+ fill (cnt.begin (), cnt.begin () + classes, 0 );
36+ for (int i = 0 ; i < n; i++)
37+ cnt[c[pn[i]]]++;
38+ for (int i = 1 ; i < classes; i++)
39+ cnt[i] += cnt[i-1 ];
40+ for (int i = n-1 ; i >= 0 ; i--)
41+ p[--cnt[c[pn[i]]]] = pn[i];
42+ cn[p[0 ]] = 0 ;
43+ classes = 1 ;
44+
45+ for (int i = 1 ; i < n; i++) {
46+ pair<int , int > cur = {c[p[i]], c[(p[i] + (1 << h)) % n]};
47+ pair<int , int > prev = {c[p[i-1 ]], c[(p[i-1 ] + (1 << h)) % n]};
48+ if (cur != prev)
49+ ++classes;
50+ cn[p[i]] = classes - 1 ;
51+ }
52+ c.swap (cn);
53+ }
54+ return p;
55+ }
56+
57+ vector<int > suffix_array (string s) {
58+ s += " $" ;
59+ vector<int > sorted_shifts = sort_cyclic_shifts (s);
60+ sorted_shifts.erase (sorted_shifts.begin ());
61+ return sorted_shifts;
8462}
0 commit comments