Advertisement
IanisBelu

E. Sneetches and Speeches 2

Dec 11th, 2023
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.56 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. using namespace std;
  27.  
  28. template <typename T>
  29. bool ckmax(T &a, T b) { return a < b ? a = b, true : false; }
  30. template <typename T>
  31. bool ckmin(T &a, T b) { return a > b ? a = b, true : false; }
  32.  
  33. using ll = long long;
  34. using pii = pair<int, int>;
  35.  
  36. const int NMAX = 3e5+5;
  37.  
  38. struct Treap {
  39.    bool val, lazy1, lazy2;
  40.    int max;
  41.    bool vall, valr;
  42.    int cntl, cntr;
  43.    int pr, size;
  44.    Treap *l, *r;
  45.    Treap(bool val): val(val), lazy1(false), lazy2(false), max(1), vall(val), valr(val), cntl(1), cntr(1), size(1), l(nullptr), r(nullptr) {
  46.       static mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  47.       pr = int(rng());
  48.    }
  49. };
  50.  
  51. int tsize(Treap *a) { return a ? a->size : 0; }
  52. int tmax(Treap *a)  { return a ? a->max  : 0; }
  53.  
  54. Treap *tpropag(Treap *a) {
  55.    if (!a) return nullptr;
  56.  
  57.    auto propag1 = [&]() {
  58.       a->val  ^= true;
  59.       a->vall ^= true;
  60.       a->valr ^= true;
  61.  
  62.       if (a->l) a->l->lazy1 ^= true;
  63.       if (a->r) a->r->lazy1 ^= true;
  64.    };
  65.  
  66.    auto propag2 = [&]() {
  67.       swap(a->cntl, a->cntr);
  68.       swap(a->vall, a->valr);
  69.  
  70.       swap(a->l, a->r);
  71.  
  72.       if (a->l) a->l->lazy2 ^= true;
  73.       if (a->r) a->r->lazy2 ^= true;
  74.    };
  75.  
  76.    if (a->lazy1) propag1();
  77.    if (a->lazy2) propag2();
  78.  
  79.    a->lazy1 = a->lazy2 = false;
  80.    
  81.    return a;
  82. }
  83.  
  84. Treap *tupdate(Treap *a) {
  85.    if (!a) return a;
  86.  
  87.    a->size = tsize(a->l) + tsize(a->r) + 1;
  88.  
  89.    tpropag(a);
  90.    tpropag(a->l);
  91.    tpropag(a->r);
  92.  
  93.    if (a->l && a->r) {
  94.       bool lfull = tsize(a->l) == a->l->cntl;
  95.       bool rfull = tsize(a->r) == a->r->cntr;
  96.  
  97.       if (lfull && rfull && a->val == a->l->val && a->val == a->r->val) {
  98.          a->cntl = a->cntr = tsize(a);
  99.          a->vall = a->valr = a->val;
  100.          a->max = tsize(a);
  101.       } else {
  102.          a->cntl = a->l->cntl + (a->val == a->l->vall && lfull);
  103.          a->cntr = a->r->cntr + (a->val == a->r->valr && rfull);
  104.  
  105.          if (a->val == a->l->valr && a->val == a->r->vall) {
  106.             if (lfull)
  107.                a->cntl += a->r->cntl;
  108.             else if (rfull)
  109.                a->cntr += a->l->cntr;
  110.          }
  111.  
  112.          a->vall = a->l->vall;
  113.          a->valr = a->r->valr;
  114.  
  115.          a->max = a->l->cntr * (a->l->valr == a->val) + 1 + a->r->cntl * (a->r->vall == a->val);
  116.       }
  117.    } else if (a->l) {
  118.       a->cntl = a->l->cntl + (a->val == a->l->vall && a->l->cntl == tsize(a->l));
  119.       a->cntr = a->l->cntr * (a->val == a->l->valr) + 1;
  120.  
  121.       a->vall = a->l->vall;
  122.       a->valr = a->val;
  123.  
  124.       a->max = a->cntr;
  125.    } else if (a->r) {
  126.       a->cntl = a->r->cntl * (a->val == a->r->vall) + 1;
  127.       a->cntr = a->r->cntr + (a->val == a->r->valr && a->r->cntr == tsize(a->r));
  128.  
  129.       a->vall = a->val;
  130.       a->valr = a->r->valr;
  131.  
  132.       a->max = a->cntl;
  133.    } else {
  134.       a->cntl = a->cntr = 1;
  135.       a->vall = a->valr = a->val;
  136.       a->max = 1;
  137.    }
  138.  
  139.    ckmax(a->max, tmax(a->l));
  140.    ckmax(a->max, tmax(a->r));
  141.  
  142.    return a;
  143. }
  144.  
  145. ostream &operator<<(ostream &out, Treap *treap) {
  146.    function<void(Treap*)> dfs = [&](Treap *treap) {
  147.       if (!treap) return;
  148.       treap = tpropag(treap);
  149.       dfs(treap->l);
  150.       out << treap->val;
  151.       dfs(treap->r);
  152.    };
  153.    dfs(treap);
  154.    return out;
  155. }
  156.  
  157. Treap *join(Treap *a, Treap *b) {
  158.    if (!a || !b) return a ? a : b;
  159.    tpropag(a);
  160.    tpropag(b);
  161.    if (a->pr < b->pr) return a->r = join(a->r, b), tupdate(a);
  162.    return b->l = join(a, b->l), tupdate(b);
  163. }
  164.  
  165. Treap *join(vector<Treap*> v) {
  166.    if (v.empty()) return nullptr;
  167.    Treap *ret = v[0];
  168.    for (int i = 1; i < sz(v); i++)
  169.       ret = join(ret, v[i]);
  170.    return ret;
  171. }
  172.  
  173. pair<Treap*, Treap*> split(Treap *a, int size) {
  174.    if (!a) return { nullptr, nullptr };
  175.    tpropag(a);
  176.    if (tsize(a->l) + 1 <= size) {
  177.       auto [ l, r ] = split(a->r, size - tsize(a->l) - 1);
  178.       a->r = l;
  179.       return { tupdate(a), r };
  180.    }
  181.    auto [ l, r ] = split(a->l, size);
  182.    a->l = r;
  183.    return { l, tupdate(a) };
  184. }
  185.  
  186. int n, q;
  187. char a[NMAX];
  188.  
  189. void read() {
  190.    cin >> n >> q >> (a + 1);
  191. }
  192.  
  193. tuple<Treap*, Treap*, Treap*> split_segment(Treap *treap, int l, int r) {
  194.    auto [ a, suff ] = split(treap, l - 1);
  195.    auto [ mid, b  ] = split(suff, r - l + 1);
  196.    return { a, mid, b };
  197. }
  198.  
  199. Treap *update1(Treap *treap, int l, int r) {
  200.    auto [ a, mid, b ] = split_segment(treap, l, r);
  201.    mid->lazy1 ^= true;
  202.    return join({ a, mid, b });
  203. }
  204.  
  205. Treap *update2(Treap *treap, int l, int r) {
  206.    auto [ a, mid, b ] = split_segment(treap, l, r);
  207.    mid->lazy2 ^= true;
  208.    return join({ a, mid, b });
  209. }
  210.  
  211. void solve() {
  212.    Treap *treap = new Treap(a[1] - '0');
  213.    for (int i = 2; i <= n; i++) {
  214.       treap = join(treap, new Treap(a[i] - '0'));
  215.    }
  216.  
  217.    while (q--) {
  218.       int t, l, r;
  219.       cin >> t >> l >> r;
  220.       if (t == 1) {
  221.          treap = update1(treap, l, r);
  222.       } else if (t == 2) {
  223.          treap = update2(treap, l, r);
  224.       }
  225.       tupdate(treap);
  226.       cout << tmax(treap) << endl;
  227.    }
  228. }
  229.  
  230. signed main() {
  231. #ifdef LOCAL
  232.    freopen("input.txt", "r", stdin);
  233. #endif
  234.    ios_base::sync_with_stdio(false);
  235.    cin.tie(0);
  236.    cout.tie(0);
  237.  
  238.    read();
  239.    solve();
  240.  
  241.    return 0;
  242. }
  243.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement