Advertisement
Dang_Quan_10_Tin

Suffix Array

Nov 16th, 2021 (edited)
840
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.19 KB | None | 0 0
  1. // string and array pos start from 0
  2. // but array sa and lcp start from 1
  3.  
  4. struct SuffixArray
  5. {
  6.     string s;
  7.     vector<int> sa, lcp, pos;
  8.     int n;
  9.  
  10.     #define ModSum(x, y) (((x + y) % n + n) % n)
  11.  
  12.     void Assign(const string & p)
  13.     {
  14.         s = p;
  15.         s += char('a' - 1);
  16.         n = s.size();
  17.  
  18.         sa.resize(n + 1);
  19.         lcp.resize(n + 1);
  20.         pos.resize(n + 1);
  21.  
  22.         vector<int> tmpsa(n + 1), in(n + 1),
  23.         tmpin(n + 1), cnt(max(n, 256) + 1, 0);
  24.  
  25.         for(auto i : s)
  26.             ++cnt[i - 'a' + 1];
  27.  
  28.         for(int i = 1; i <= 26; ++i)
  29.             cnt[i] += cnt[i - 1];
  30.  
  31.         for(int i = n - 1; ~i; --i)
  32.             sa[--cnt[s[i] - 'a' + 1]] = i;
  33.  
  34.         for(int i = 0; i < n; ++i)
  35.             in[sa[i]] = i == 0 ? 0 : (in[sa[i - 1]] + (s[sa[i]] != s[sa[i - 1]]));
  36.  
  37.         for(int i = 0, maxn = in[sa[n - 1]]; (1 << i) <= n; ++i)
  38.         {
  39.             for(int j = 0; j <= maxn; ++j)
  40.                 cnt[j] = 0;
  41.  
  42.             for(int j = 0; j < n; ++j)
  43.                 ++cnt[in[sa[j]]];
  44.  
  45.             for(int j = 1; j <= maxn; ++j)
  46.                 cnt[j] += cnt[j - 1];
  47.  
  48.             for(int j = n - 1; ~j; --j)
  49.                 tmpsa[--cnt[in[ModSum(sa[j], -(1 << i))]]] = ModSum(sa[j], -(1 << i));
  50.  
  51.             for(int j = 0; j < n; ++j)
  52.             {
  53.                 sa[j] = tmpsa[j];
  54.                 tmpin[sa[j]] = j == 0 ? 0 : (tmpin[sa[j - 1]] +
  55.                                              (make_pair(in[sa[j]], in[ModSum(sa[j], 1 << i)]) !=
  56.                                               make_pair(in[sa[j - 1]], in[ModSum(sa[j - 1], 1 << i)])));
  57.             }
  58.  
  59.             maxn = tmpin[sa[n - 1]];
  60.             swap(in, tmpin);
  61.         }
  62.  
  63.         s.pop_back();
  64.         --n;
  65.     }
  66.  
  67.     void LCP() {
  68.         for(int i = 0; i < n; ++i)
  69.             pos[sa[i + 1]] = i + 1;
  70.  
  71.         for(int i = 0, k = 0; i < n; ++i) {
  72.             if(pos[i] == n) {
  73.                 lcp[pos[i]] = k = 0;
  74.                 continue;
  75.             }
  76.  
  77.             while(k + i < n && sa[pos[i] + 1] + k < n && s[k + i] == s[sa[pos[i] + 1] + k])
  78.                 ++k;
  79.             lcp[pos[i]] = k;
  80.             k = max(k - 1, 0);
  81.         }
  82.     }
  83. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement