Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <iostream>
- #include <string>
- #include <vector>
- using namespace std;
- string s;
- vector <long long> h;
- vector <int> suff;
- vector <long long> degrees;
- long long module = 10000000019;
- long long c = 31;
- bool comp_suff(int, int);
- void initialize() {
- cin >> s;
- h.resize(s.size());
- h[0] = s[0] - 'a' + 1;
- long long p = c;
- degrees.push_back(c);
- for (int i = 1; i < h.size(); ++i) {
- h[i] = h[i - 1] + ((s[i] - 'a' + 1) * p);
- p *= c;
- degrees.push_back(p);
- }
- for (int i = s.size() - 1; i >= 0; --i)
- suff.push_back(i);
- sort(suff.begin(), suff.end(), comp_suff);
- for (int i = 0; i < s.size(); ++i)
- cout << suff[i] + 1 << ' ';
- }
- bool comp_substr(int l1, int r1, int l2, int r2) {
- if (r2 - l2 != r1 - l1)
- return false;
- else {
- long long h1 = (l1 == 0) ? h[r1] : h[r1] - h[l1 - 1],
- h2 = (l2 == 0) ? h[r2] : h[r2] - h[l2 - 1];
- if (l1 < l2)
- h1 *= degrees[l2 - l1 - 1];
- else
- h2 *= degrees[l1 - l2 - 1];
- if (h1 == h2)
- return true;
- else return false;
- }
- }
- int max_common_prefix(int a, int b) {
- int left = 0, right = min(s.size() - a, s.size() - b) - 1;
- int answer = -1;
- while (left < right && right >= answer) {
- int median = (left + right) / 2;
- if (comp_substr(a, a + median, b, b + median)) {
- answer = median;
- left = median + 1;
- }
- else
- right = median;
- }
- return answer;
- }
- bool comp_suff(int a, int b) {
- int k = max_common_prefix(a, b) + 1;
- if (a + k == s.size() || (b + k != s.size() && s[a + k] < s[b + k]))
- return true;
- else
- return false;
- }
- int main() {
- initialize();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement