Advertisement
Guest User

SuffixArray

a guest
Jul 26th, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.38 KB | None | 0 0
  1. const int N = 1e5 + 10;
  2. int sum(int a, int b, int p)
  3. {
  4.     a += b;
  5.     return a >= p ? a - p : a;
  6. }
  7. int sub(int a, int b, int p)
  8. {
  9.     return sum(a, p - b, p);
  10. }
  11.  
  12. struct SuffixArray
  13. {
  14.     int lcp[N];
  15.     int cl[N], pos[N];
  16.     int cl_n[N], pos_n[N];
  17.     int cnt[N];
  18.     int n;
  19.     string s;
  20.     void eprint()
  21.     {
  22.         for(int i = 0; i < n; ++i)
  23.         {
  24.             auto p = pos[i];
  25.             eprintf("%s\n", s.c_str() + p);
  26.         }
  27.         puts("");
  28.     }
  29.     int calc_cl(function<bool(int, int)> equals)
  30.     {
  31.         cl_n[pos[0]] = 0;
  32.         int cl_cnt = 1;
  33.         for(int i = 1; i < n; ++i)
  34.         {
  35.             if (!equals(pos[i], pos[i - 1]))
  36.                 ++cl_cnt;
  37.             cl_n[pos[i]] = cl_cnt - 1;
  38.         }
  39.         copy(cl_n, cl_n + n, cl);
  40.         return cl_cnt;
  41.     }
  42.     void sort_pos(int cl_cnt, int offset)
  43.     {
  44.         for (int i = 0; i < n; ++i)
  45.             pos_n[i] = sub(pos[i], offset, n);
  46.         fill(cnt, cnt + cl_cnt, 0);
  47.         for (int i = 0; i < n; ++i)
  48.             ++cnt[cl[i]];
  49.         for (int i = 1; i < cl_cnt; ++i)
  50.             cnt[i] += cnt[i - 1];
  51.         for (int i = n - 1; i >= 0; --i)
  52.             pos[--cnt[cl[pos_n[i]]]] = pos_n[i];
  53.     }
  54.     void build(string s)
  55.     {
  56.         this->s = s;
  57.         n = s.size();
  58.         for (int i = 0; i < n; ++i)
  59.         {
  60.             pos[i] = i;
  61.             cl[i] = s[i];
  62.         }
  63.         for(int h = 1, cl_cnt = N; h == 1 || cl_cnt < n; h <<= 1)
  64.         {
  65.             auto step = h >> 1;
  66.             sort_pos(cl_cnt, step);
  67.             cl_cnt = calc_cl([&](int a, int b) { return cl[a] == cl[b] && cl[sum(a, step, n)] == cl[sum(b, step, n)]; });
  68.             eprint();
  69.         }
  70.     }
  71. } sa;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement