URL: https://www.luogu.org/problem/P3809
Meaning of the questions:
All the suffixes of strings sorted in lexicographic order. String length is less than $ 1e6 $.
answer:
Bare suffix array, the principle is first start position is $ I $ suffix as a first key, $ i + 1 $ as the second keyword, keywords are then combined to obtain a new first key, then $ i + 2 $ as a second key, and then combined, followed by multiplication. See the specific implementation code comments:
Reference blog:
https://www.cnblogs.com/victorique/p/8480093.html
https://www.luogu.org/blog/black-jokers/solution1-p3809
https://www.cnblogs.com/ezoiLZH/p/9607849.html
AC Code:
#include <bits / STDC ++ H.> the using namespace STD; const int MAXN = 1000005; struct SuffixArray { int n-, m; int Tax [MAXN], Rank [MAXN], TP [MAXN], SA [MAXN]; // sa [i] = j, i-th name suffixes j from the start (note that the deposit subscript) // Rank [i] = j, i from the beginning of the suffix j are the names (and reciprocal sa , a position (value)) // TP [i], the second is keyword suffix i j from the beginning (sa array equivalent to the second keyword, is stored index) // Tax [i] = j, i represents a first number of keywords having j (with the tub when the radix sort is a value) char CH [MAXN]; void Sort () // radix sort { for (int i = 0; i < = m; ++ i) // clears the tub Tax [I] = 0; for (int I =. 1; I <= n-; I ++) // number into each of the corresponding barrel, are obtained from the first key is the start suffix i of Rank [i] name, // ranking suffixes are such tax [rank [i]] a ++ tax [rank [i]] ; for (int i = 1; i <= m; ++ i) / / plus in front of the bucket, the sort is complete, to get rankings Tax [I] + = Tax [-I. 1]; for (int I = n-; I > = 1; - i) // i is a suffix to the second key is a suffix tp [i], tax [rank [tp [i]]] = j i is the second key is // word suffix first keyword suffix first keyword having j, since the radix sort and find the prefix already know the position, so that put // a rank corresponding to the suffix tp [i] is recorded, while Save ranking 1. Every time i take the first key to a second key suffix // suffix of the first to the last keyword, like this is the same as the equivalent of the second key, sorted according to the first keyword , if the second hurdle after // key word is not the same, is the first large keyword, the more certain by this time to ensure that the first and second sorted by keyword. SA [Tax [Rank [tp [I]]] -] = tp [I]; } BOOL CMP (A int, int B, int K) { // tp is now the last Rank, // foregoing paragraphs meaning from the sa [i] and start from the sa [i-1] is the beginning of the suffix whether the same ranking, // item after the same token, after the addition of j means that the comparison ranking is the second key. Guaranteed without crossing return TP [A] == TP [B] && TP [A + K] == TP [B + K]; } get_sa void () { n-= strlen (CH +. 1); for (int I =. 1; I <= n-; ++ I) m = max (m, Rank [I] = CH [I] - '0'), TP [I] = I; // The first round of ASCII code first key press, the second press number key sort (); // a first round of radix sort for (int p = 0, j = 1; p <n; j << = 1, P = m) { P = 0; // clear for (int i =. 1; i <= J; i ++) TP [P ++] = n-J-i +; // these latter less suffixes i j, and only its own, so at the bottom surface, by reducing the length of the second key is increased for (int I =. 1; I <= n-; I ++) IF (SA [I]> j) tp [++ p] = sa [ i] -j; // sa [i]> j proof suffix length i is greater than j, tp [sa [i] -j] is a suffix sa [i] -j second keywords, while still out of order sort (); // second round and beyond radix sort swap (rank, tp); // tp no use, we will rank the information copied to tp. While the vacant rank rank [sa [1]] = p = 1; // vacant rank correspondence relationship recorded in the new sa, carried out at a sorting for (int I = 2; I <= n-; I ++) rank [SA [I]] = CMP (SA [I], SA [-I. 1], J) P: ++? p; } } }; SuffixArray sa; int main() { //scanf("%d",&sa.n); scanf("%s",sa.ch+1); sa.get_sa(); for(int i=1;i<=sa.n;++i) printf("%d%c",sa.sa[i],(i==sa.n?'\n':' ')); return 0; }