leoanjos

Odeio o UVa

Sep 14th, 2021 (edited)
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.41 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define long long long int
  6.  
  7. struct SegmentTree {
  8. private:
  9.     int N;
  10.     string S;
  11.     vector<bool> changed;
  12.     vector<int> tree, lazy;
  13.  
  14. public:
  15.     SegmentTree(int N, string S) {
  16.         this->N = N;
  17.         this->S = S;
  18.  
  19.         changed.assign(4 * N, false);
  20.         tree.assign(4 * N, 0);
  21.         lazy.resize(4 * N);
  22.  
  23.         build(1, 1, N);
  24.     }
  25.  
  26.     void update(int l, int r, int v) {
  27.         update(1, 1, N, l, r, v);
  28.     }
  29.  
  30.     int query(int l, int r) {
  31.         return query(1, 1, N, l, r);
  32.     }
  33.  
  34. private:
  35.     void update_tree(int i) {
  36.         tree[i] = tree[2 * i] + tree[2 * i + 1];
  37.     }
  38.  
  39.     void update_lazy(int i, int l, int r, int v) {
  40.         if (l == r) tree[i] = v >= 0 ? v : 1 - tree[i];
  41.  
  42.         if (v >= 0 || !changed[i]) {
  43.             lazy[i] = v;
  44.             changed[i] = true;
  45.  
  46.             if (!v) tree[i] = 0;
  47.             else if (v > 0) tree[i] = r - l + 1;
  48.             else tree[i] = r - l - tree[i] + 1;
  49.         } else if (lazy[i] >= 0) {
  50.             lazy[i] = 1 - lazy[i];
  51.             tree[i] = lazy[i] ? r - l + 1 : 0;
  52.         } else {
  53.             changed[i] = false;
  54.             tree[i] = r - l - tree[i] + 1;
  55.         }
  56.     }
  57.  
  58.     void build(int i, int l, int r) {
  59.         if (l == r) tree[i] = S[l] == '1';
  60.         else {
  61.             int m = (l + r) / 2;
  62.             build(2 * i, l, m);
  63.             build(2 * i + 1, m + 1, r);
  64.             update_tree(i);
  65.         }
  66.     }
  67.  
  68.     void update(int i, int l, int r, int ul, int ur, int v) {
  69.         if (r < ul || l > ur) return;
  70.  
  71.         if (l == r) tree[i] = v >= 0 ? v : 1 - tree[i];
  72.         else if (ul <= l && r <= ur) update_lazy(i, l, r, v);
  73.         else {
  74.             int m = (l + r) / 2;
  75.             if (changed[i]) {
  76.                 changed[i] = false;
  77.                 update_lazy(2 * i, l, m, lazy[i]);
  78.                 update_lazy(2 * i + 1, m + 1, r, lazy[i]);
  79.             }
  80.  
  81.             update(2 * i, l, m, ul, ur, v);
  82.             update(2 * i + 1, m + 1, r, ul, ur, v);
  83.             update_tree(i);
  84.         }
  85.     }
  86.  
  87.     int query(int i, int l, int r, int ql, int qr) {
  88.         if (r < ql || l > qr) return 0;
  89.         if (ql <= l && r <= qr) return tree[i];
  90.  
  91.         int m = (l + r) / 2;
  92.         if (changed[i]) {
  93.             changed[i] = false;
  94.             update_lazy(2 * i, l, m, lazy[i]);
  95.             update_lazy(2 * i + 1, m + 1, r, lazy[i]);
  96.         }
  97.  
  98.         return query(2 * i, l, m, ql, qr) + query(2 * i + 1, m + 1, r, ql, qr);
  99.     }
  100. };
  101.  
  102. int main() {
  103.     ios_base::sync_with_stdio(false);
  104.     cin.tie(NULL);
  105.  
  106.     int T; cin >> T;
  107.     for (int t = 1; t <= T; t++) {
  108.         cout << "Case " << t << ":\n";
  109.  
  110.         int M; cin >> M;
  111.  
  112.         string S = ".";
  113.         while (M--) {
  114.             int num_concat; cin >> num_concat;
  115.             string concat; cin >> concat;
  116.             while (num_concat--) S += concat;
  117.         }
  118.  
  119.         int N = S.size() - 1;
  120.         SegmentTree tree(N, S);
  121.  
  122.         int Q; cin >> Q;
  123.         int num_query = 1;
  124.  
  125.         while (Q--) {
  126.             char op; int a, b;
  127.             cin >> op >> a >> b;
  128.  
  129.             if (op == 'F') tree.update(a + 1, b + 1, 1);
  130.             else if (op == 'E') tree.update(a + 1, b + 1, 0);
  131.             else if (op == 'I') tree.update(a + 1, b + 1, -1);
  132.             else cout << "Q" << num_query++ << ": " << tree.query(a + 1, b + 1) << "\n";
  133.         }
  134.     }
  135. }
Add Comment
Please, Sign In to add comment