Advertisement
IanisBelu

B. Pear TreaP

Dec 10th, 2023
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.47 KB | Source Code | 0 0
  1. #ifdef LOCAL
  2. #include <iostream>
  3. #include <fstream>
  4. #include <iomanip>
  5. #include <random>
  6. #include <vector>
  7. #include <queue>
  8. #include <stack>
  9. #include <set>
  10. #include <map>
  11. #else
  12. #pragma GCC optimize("Ofast,unroll-loops")
  13. #include <bits/stdc++.h>
  14. #define cerr if (false) cerr
  15. #define endl '\n'
  16. #endif
  17.  
  18. #define fi first
  19. #define se second
  20.  
  21. #define sz(a) ((int)(a).size())
  22. #define all(a) (a).begin(), (a).end()
  23.  
  24. #define lsb(x) (x & (-x))
  25.  
  26. #define YES cout << "yes" << endl
  27. #define NO  cout << "no" << endl
  28.  
  29. using namespace std;
  30.  
  31. template <typename T>
  32. bool ckmax(T &a, T b) { return a < b ? a = b, true : false; }
  33. template <typename T>
  34. bool ckmin(T &a, T b) { return a > b ? a = b, true : false; }
  35.  
  36. using ll = long long;
  37. using pii = pair<int, int>;
  38.  
  39. const int NMAX = 3e5+5;
  40. const int MOD = 869691499;
  41. const int A = 59;
  42.  
  43. int n, q;
  44. char a[NMAX];
  45.  
  46. int lgpow(int a, int n) {
  47.    if (n == 0) return 1;
  48.    if (n & 1) return 1ll * a * lgpow(a, n ^ 1) % MOD;
  49.    int p = lgpow(a, n >> 1);
  50.    return 1ll * p * p % MOD;
  51. }
  52.  
  53. struct Treap {
  54.    char val;
  55.    int pr, size;
  56.    int hsh;
  57.    Treap *l, *r;
  58.  
  59.    Treap(): val(0), pr(0), size(0), hsh(0), l(nullptr), r(nullptr) { }
  60.    Treap(char _val): val(_val), size(1), hsh(1ll * (_val - 'a' + 1) * A % MOD), l(nullptr), r(nullptr) {
  61.       static mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  62.       pr = int(rng());
  63.    }
  64. };
  65.  
  66. ostream &operator<<(ostream &out, Treap *t) {
  67.    function<void(Treap*)> dfs = [&](Treap *t) {
  68.       if (!t) return;
  69.       dfs(t->l);
  70.       out << t->val;
  71.       dfs(t->r);
  72.    };
  73.    dfs(t);
  74.    return out;
  75. }
  76.  
  77. int size(Treap *a) { return a ? a->size : 0; }
  78. int hsh(Treap *a) { return a ? a->hsh : 0; }
  79.  
  80. Treap *treap_update(Treap *a) {
  81.    if (!a) return nullptr;
  82.    a->size = size(a->l) + size(a->r) + 1;
  83.    a->hsh = hsh(a->l);
  84.    int p = lgpow(A, size(a->l) + 1);
  85.    a->hsh = 1ll * (1ll * a->hsh + 1ll * (a->val - 'a' + 1) * p) % MOD;
  86.    a->hsh = 1ll * (1ll * a->hsh + 1ll * hsh(a->r) * p) % MOD;
  87.    return a;
  88. }
  89.  
  90. Treap *join(Treap *a, Treap *b) {
  91.    if (!a || !b) return a ? a : b;
  92.    if (a->pr > b->pr) return a->r = join(a->r, b), treap_update(a);
  93.    return b->l = join(a, b->l), treap_update(b);
  94. }
  95.  
  96. Treap *join(vector<Treap*> treaps) {
  97.    if (treaps.empty()) return nullptr;
  98.    Treap *ret = treaps[0];
  99.    for (int i = 1; i < sz(treaps); i++)
  100.       ret = join(ret, treaps[i]);
  101.    return ret;
  102. }
  103.  
  104. pair<Treap*, Treap*> split(Treap *a, int pos) {
  105.    if (!a) return { nullptr, nullptr };
  106.    if (size(a->l) + 1 <= pos) {
  107.       auto [ l, r ] = split(a->r, pos - size(a->l) - 1);
  108.       a->r = l;
  109.       return { treap_update(a), r };
  110.    }
  111.    auto [ l, r ] = split(a->l, pos);
  112.    a->l = r;
  113.    return { l, treap_update(a) };
  114. }
  115.  
  116. tuple<Treap*, Treap*, Treap*> split_segment(Treap *treap, int l, int r) {
  117.    auto [ a, suff ] = split(treap, l - 1);
  118.    auto [ mid, b  ] = split(suff, r - l + 1);
  119.    return { a, mid, b };
  120. }
  121.  
  122. Treap *remove_segment(Treap *treap, int l, int r) {
  123.    auto [ a, mid, b ] = split_segment(treap, l, r);
  124.    return join(a, b);
  125. }
  126.  
  127. Treap *insert(Treap *treap, int pos, char val) {
  128.    auto [ l, r ] = split(treap, pos - 1);
  129.    return join({ l, new Treap(val), r });
  130. }
  131.  
  132. bool query(Treap *t1, Treap *t2, int l, int r) {
  133.    auto [ left1, mid1, right1 ] = split_segment(t1, l, r);
  134.    auto [ left2, mid2, right2 ] = split_segment(t2, n - r + 1, n - l + 1);
  135.  
  136.    bool ret = mid1->hsh == mid2->hsh;
  137.  
  138.    join({ left1, mid1, right1 });
  139.    join({ left2, mid2, right2 });
  140.  
  141.    return ret;
  142. }
  143.  
  144. void read() {
  145.    cin >> n >> q >> (a + 1);
  146. }
  147.  
  148. void solve() {
  149.    Treap *t1 = new Treap(a[1]);
  150.    Treap *t2 = new Treap(a[n]);
  151.    for (int i = 2; i <= n; i++) {
  152.       t1 = join(t1, new Treap(a[i]));
  153.       t2 = join(t2, new Treap(a[n - i + 1]));
  154.    }
  155.  
  156.    for (int i = 1; i <= q; i++) {
  157.       char c;
  158.       int t, l, r, p;
  159.       cin >> t;
  160.       if (t == 1) {
  161.          cin >> l >> r;
  162.          t1 = remove_segment(t1, l, r);
  163.          t2 = remove_segment(t2, n - r + 1, n - l + 1);
  164.          n -= r - l + 1;
  165.       } else if (t == 2) {
  166.          cin >> c >> p;
  167.          t1 = insert(t1, p, c);
  168.          t2 = insert(t2, n - p + 2, c);
  169.          n++;
  170.       } else {
  171.          cin >> l >> r;
  172.          if (query(t1, t2, l, r)) YES;
  173.          else NO;
  174.       }
  175.    }
  176. }
  177.  
  178. signed main() {
  179. #ifdef LOCAL
  180.    freopen("input.txt", "r", stdin);
  181. #endif
  182.    ios_base::sync_with_stdio(false);
  183.    cin.tie(0);
  184.    cout.tie(0);
  185.    
  186.    read();
  187.    solve();
  188.  
  189.    return 0;
  190. }
  191.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement