Advertisement
Mlxa

### Оптимизированный суффиксный массив

Feb 6th, 2019
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. #define long ll
  5. #define all(x) begin(x), end(x)
  6.  
  7. const int N = 1e6 + 10;
  8. vector<int> bucket[N];
  9. int equiv[N];
  10. int new_e[N];
  11. int s_arr[N];
  12. int ptr = 0;
  13.  
  14. int main() {
  15. #ifdef LC
  16.     assert(freopen("input.txt", "r", stdin));
  17.     assert(freopen("output.txt", "w", stdout));
  18. #endif
  19.     ios::sync_with_stdio(false);
  20.     cin.tie(nullptr);
  21.    
  22.     string s;
  23.     s.reserve((int)1e6);
  24.     cin >> s;
  25.     s += '#';
  26.     int n = (int)s.size();
  27.    
  28.     for (int i = 0; i < n; ++i) {
  29.         equiv[i] = s[i];
  30.         bucket[equiv[i]].push_back(i);
  31.     }
  32.     for (int i = 0; i < 256; ++i) {
  33.         for (int suf : bucket[i]) {
  34.             s_arr[ptr++] = suf;
  35.         }
  36.         bucket[i].clear();
  37.     }
  38.        
  39.     for (int l = 1; l < n; l *= 2) {
  40.         int max_class = 0;
  41.         for (int ind = 0; ind < n; ++ind) {
  42.             int suf = s_arr[ind] - l;
  43.             if (suf < 0) {
  44.                 suf += n;
  45.             }
  46.             max_class = max(max_class, equiv[suf]);
  47.             bucket[equiv[suf]].push_back(suf);
  48.         }
  49.         ptr = 0;
  50.         for (int i = 0; i <= max_class; ++i) {
  51.             for (int suf : bucket[i]) {
  52.                 s_arr[ptr++] = suf;
  53.             }
  54.             bucket[i].clear();
  55.         }
  56.         new_e[s_arr[0]] = 0;
  57.         for (int i = 1; i < n; ++i) {
  58.             int x = s_arr[i], y = s_arr[i - 1];
  59.             int z = x + l, t = y + l;
  60.             if (z >= n) {
  61.                 z -= n;
  62.             }
  63.             if (t >= n) {
  64.                 t -= n;
  65.             }
  66.             new_e[x] = new_e[y];
  67.             if (equiv[x] > equiv[y] || equiv[z] > equiv[t]) {
  68.                 ++new_e[x];
  69.             }
  70.         }
  71.         copy_n(new_e, n, equiv);
  72.     }
  73.    
  74.     for (int i = 1; i < n; ++i) {
  75.         cout << s_arr[i] << '\n';
  76.     }
  77.     cerr << "Time = " << clock() * 1000 / CLOCKS_PER_SEC << endl;
  78.     return 0;
  79. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement