#include #include #include #include #include using std::cin; using std::cout; using std::endl; using std::make_pair; using std::pair; using std::string; using std::vector; using std::swap; static void quicksort(const string &s, vector &v, int x, int l, int r) { if (l >= r) return; int p = l + rand() % (r - l + 1); swap(v[l], v[p]); char c = s[v[l] + x]; int i = l + 1; int j = r; int k = r; while (i <= j) { int C = s[v[j] + x]; if (C < c) { swap(v[i], v[j]); i++; } else if (C > c) { swap(v[j], v[k]); k--; j--; } else j--; } quicksort(s, v, x, l, i - 1); quicksort(s, v, x, k + 1, r); } static void sort(const string &s, vector &v, int x, int l, int r) { if (l >= r) return; quicksort(s, v, x, l, r); char c = s[v[l] + x]; int ll = l; for (int i = l + 1; i <= r; i++) { char C = s[v[i] + x]; if (C != c) { sort(s, v, x + 1, ll, i - 1); ll = i; c = C; } } sort(s, v, x + 1, ll, r); } // Build suffix array of the string text and // return a vector result of the same length as the text // such that the value result[i] is the index (0-based) // in text where the i-th lexicographically smallest // suffix of text starts. vector BuildSuffixArray(const string& text) { int sz = text.size(); vector v; v.reserve(text.size()); for (int i = 0; i < sz; i++) v.push_back(i); sort(text, v, 0, 0, sz - 1); return v; } int main() { string text; cin >> text; vector suffix_array = BuildSuffixArray(text); for (int i = 0; i < suffix_array.size(); ++i) { cout << suffix_array[i] << ' '; } cout << endl; return 0; }