Guest User

XXI Open Cup GP of China -- Problem G

a guest
May 2nd, 2021
1,333
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.27 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using ll = long long;
  4. const ll MOD = (ll)1e9 + 7;
  5.  
  6. class SegTree {
  7.     private:
  8.         // Store
  9.         //  Value:
  10.         //      historic sum
  11.         //      current sum (= number of ON elements)
  12.         //      time since last operation
  13.         //  Tag:
  14.         //      current time of operation
  15.         //      total time spent in TOGGLE state
  16.         //      current toggle status of operation
  17.  
  18.         struct Tag {
  19.             int cur_t = 0;
  20.             int flip_t = 0;
  21.             bool flip = 0;
  22.  
  23.             Tag() {}
  24.             Tag(int ct, bool f) { cur_t = ct, flip = f; }
  25.         };
  26.         struct Node {
  27.             ll hist_sum = 0;
  28.             int cur_zero = 0;
  29.             int cur_one = 0;
  30.             int cur_t = 0;
  31.         };
  32.  
  33.         vector<Node> seg;
  34.         vector<Tag> tag;
  35.         int global_t = 0;
  36.         int h = 1;
  37.  
  38.         void apply(int i, const Tag& t) {
  39.             int dt = t.cur_t - seg[i].cur_t;
  40.             int dt_0 = dt - t.flip_t;
  41.             int dt_1 = t.flip_t;
  42.  
  43.             seg[i].hist_sum += (ll)seg[i].cur_one * dt_0 + (ll)seg[i].cur_zero * dt_1;
  44.             if (t.flip) swap(seg[i].cur_zero, seg[i].cur_one);
  45.             seg[i].cur_t = t.cur_t;
  46.  
  47.             if (i < h) {
  48.                 tag[i].flip_t += (tag[i].flip ? dt_0 : dt_1);
  49.                 tag[i].flip ^= t.flip;
  50.                 tag[i].cur_t = t.cur_t;
  51.             }
  52.         }
  53.         void push(int i) {
  54.             apply(2*i, tag[i]);
  55.             apply(2*i+1, tag[i]);
  56.             tag[i].flip_t = 0;
  57.             tag[i].flip = 0;
  58.         }
  59.         void update(int i) {
  60.             seg[i].cur_zero = seg[2*i].cur_zero + seg[2*i+1].cur_zero;
  61.             seg[i].cur_one = seg[2*i].cur_one + seg[2*i+1].cur_one;
  62.             seg[i].hist_sum = seg[2*i].hist_sum + seg[2*i+1].hist_sum;
  63.         }
  64.  
  65.         ll recGet(int a, int b, int i, int ia, int ib) {
  66.             if (ib <= a || b <= ia) return 0;
  67.             if (a <= ia && ib <= b) return seg[i].hist_sum;
  68.             push(i);
  69.             int im = (ia + ib) >> 1;
  70.             return recGet(a, b, 2*i, ia, im) + recGet(a, b, 2*i+1, im, ib);
  71.         }
  72.         void recApply(int a, int b, const Tag& t, int i, int ia, int ib) {
  73.             if (ib <= a || b <= ia) return;
  74.             if (a <= ia && ib <= b) apply(i, t);
  75.             else {
  76.                 push(i);
  77.                 int im = (ia + ib) >> 1;
  78.                 recApply(a, b, t, 2*i, ia, im);
  79.                 recApply(a, b, t, 2*i+1, im, ib);
  80.                 update(i);
  81.             }
  82.         }
  83.     public:
  84.         SegTree(int n) {
  85.             while(h < n) h *= 2;
  86.             seg.resize(2*h);
  87.             for (int i = h; i < h + n; ++i) seg[i].cur_zero = 1;
  88.             for (int i = h-1; i > 0; --i) update(i);
  89.             tag.resize(h);
  90.         }
  91.  
  92.         ll rangeSum(int a, int b) {
  93.             // cerr << "RangeSum(" << a << ' '<< b << ")\n";
  94.             return recGet(a, b+1, 1, 0, h);
  95.         }
  96.  
  97.         void rangeToggle(int a, int b) {
  98.             // cerr << "RangeToggle(" << a << ' '<< b << ")\n";
  99.             recApply(a, b+1, Tag(global_t, 1), 1, 0, h);
  100.             ++global_t;
  101.             recApply(0, h, Tag(global_t, 0), 1, 0, h);
  102.         }
  103. };
  104.  
  105. int main() {
  106.     ios_base::sync_with_stdio(false);
  107.     cin.tie(0);
  108.    
  109.     int n;
  110.     cin >> n;
  111.  
  112.     vector<int> as(n);
  113.     for (int& a : as) {
  114.         cin >> a;
  115.         --a;
  116.     }
  117.  
  118.     vector<int> lst(n, n);
  119.     vector<int> nxt(n, n);
  120.     for (int i = n-1; i >= 0; --i) {
  121.         nxt[i] = lst[as[i]];
  122.         lst[as[i]] = i;
  123.     }
  124.    
  125.     int q;
  126.     cin >> q;
  127.     vector<ll> ans(q, 0);
  128.     vector<vector<pair<int, int>>> qs(n);
  129.     for (int qi = 0; qi < q; ++qi) {
  130.         int a, b;
  131.         cin >> a >> b;
  132.         --a; --b;
  133.         qs[a].emplace_back(b, qi);
  134.     }
  135.  
  136.     SegTree seg(n);
  137.     for (int i = n-1; i >= 0; --i) {
  138.         seg.rangeToggle(i, nxt[i] - 1);
  139.         for (auto& pr : qs[i]) {
  140.             int j = pr.first;
  141.             ans[pr.second] = seg.rangeSum(i, j);
  142.         }
  143.     }
  144.  
  145.     for (ll& v : ans) cout << v << '\n';
  146. }
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
Advertisement
Add Comment
Please, Sign In to add comment