Advertisement
ke_timofeeva7

suffix array, lcp

Oct 27th, 2023
499
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.92 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <sstream>
  4. #include <cmath>
  5. #include <memory.h>
  6. #include <algorithm>
  7. #include <stack>
  8. #include <deque>
  9. #include <iomanip>
  10. #include <stdio.h>
  11. #include <queue>
  12. #include <map>
  13. #include <set>
  14. #include <unordered_map>
  15. #include <unordered_set>
  16. #include <random>
  17. #include <ctime>
  18. #include <cstdlib>
  19. #include <cassert>
  20. #include <iterator>
  21. #include <chrono>
  22. #include <array>
  23. #include <bitset>
  24. #define pii pair <long long, long long>
  25. #define debug(x) cerr << (#x) << " " << (x) << endl
  26. #define pb push_back
  27. #define all(vc) vc.begin(), vc.end()
  28. #define endl "\n"
  29. using namespace std;
  30.  
  31. mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
  32.  
  33. const long long ABC = 300;
  34.  
  35. void suffix_array(string& s, vector<int>& p, vector<int>& c, vector<int>& lcp) {
  36.     s += "$";
  37.     int n = (int)(s.size());
  38.     p.resize(n);
  39.     c.resize(n);
  40.     vector<int> cnt(ABC);
  41.     for (int i = 0; i < n; i++) {
  42.         cnt[s[i]]++;
  43.     }
  44.     for (int i = 1; i < ABC; i++) {
  45.         cnt[i] += cnt[i - 1];
  46.     }
  47.     for (int i = 0; i < n; i++) {
  48.         p[--cnt[s[i]]] = i;
  49.     }
  50.     c[p[0]] = 0;
  51.     int cls = 1;
  52.     for (int i = 1; i < n; i++) {
  53.         c[p[i]] = c[p[i - 1]];
  54.         if (s[p[i]] != s[p[i - 1]]) {
  55.             c[p[i]]++;
  56.             cls++;
  57.         }
  58.     }
  59.     vector<int> pn(n);
  60.     for (int k = 0; (1LL << k) < n; k++) {
  61.         for (int i = 0; i < n; i++) {
  62.             pn[i] = (n + p[i] - (1 << k)) % n;
  63.         }
  64.         cnt.assign(cls, 0);
  65.         for (int i = 0; i < n; i++) {
  66.             cnt[c[pn[i]]]++;
  67.         }
  68.         for (int i = 1; i < cls; i++) {
  69.             cnt[i] += cnt[i - 1];
  70.         }
  71.         for (int i = n - 1; i >= 0; i--) {
  72.             p[--cnt[c[pn[i]]]] = pn[i];
  73.         }
  74.         vector<int> cn(n);
  75.         cn[p[0]] = 0;
  76.         int clss = 0;
  77.         for (int i = 1; i < n; i++) {
  78.             cn[p[i]] = cn[p[i - 1]];
  79.             pii a = { c[p[i]], c[(p[i] + (1LL << k)) % n] };
  80.             pii b = { c[p[i - 1]], c[(p[i - 1] + (1LL << k)) % n] };
  81.             if (a != b) {
  82.                 cn[p[i]]++;
  83.                 clss++;
  84.             }
  85.         }
  86.         cls = clss + 1;
  87.         c.swap(cn);
  88.     }
  89.     lcp.resize(n);
  90.     int l = 0;
  91.     for (int i = 0; i < n; i++) {
  92.         if (c[i] == n - 1) {
  93.             continue;
  94.         }
  95.         int nxt = p[c[i] + 1];
  96.         while (max(i, nxt) + l < n && s[i + l] == s[nxt + l]) {
  97.             l++;
  98.         }
  99.         lcp[c[i]] = l;
  100.         l = max(0, l - 1);
  101.     }
  102. }
  103. signed main() {
  104.     ios_base::sync_with_stdio(0);
  105.     cin.tie(0);
  106.     cout.tie(0);
  107.     srand(time(0));
  108.     cout.precision(17);
  109.  
  110.     int n;
  111.     cin >> n;
  112.     string s;
  113.     cin >> s;
  114.     vector<int> p(n), c, lcp;
  115.     for (int &i : p) {
  116.         cin >> i;
  117.     }
  118.     suffix_array(s, p, c, lcp);
  119.     for (int i = 1; i < (int)(p.size()) - 1; i++) {
  120.         cout << lcp[i] << endl;
  121.     }
  122.     return 0;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement