Advertisement
pb_jiang

LC biweek 98 T4 AC

Feb 18th, 2023 (edited)
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.76 KB | None | 0 0
  1. namespace atcoder
  2. {
  3.  
  4. template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S), F (*composition)(F, F), F (*id)()>
  5. struct lazy_segtree {
  6.     int ceil_pow2(int n)
  7.     {
  8.         int x = 0;
  9.         while ((1U << x) < (unsigned int) (n))
  10.             x++;
  11.         return x;
  12.     }
  13.  
  14.   public:
  15.     lazy_segtree() : lazy_segtree(0) {}
  16.     explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
  17.     explicit lazy_segtree(const std::vector<S> &v) : _n(int(v.size()))
  18.     {
  19.         log = ceil_pow2(_n);
  20.         size = 1 << log;
  21.         d = std::vector<S>(2 * size, e());
  22.         lz = std::vector<F>(size, id());
  23.         for (int i = 0; i < _n; i++)
  24.             d[size + i] = v[i];
  25.         for (int i = size - 1; i >= 1; i--) {
  26.             update(i);
  27.         }
  28.     }
  29.  
  30.     void set(int p, S x)
  31.     {
  32.         assert(0 <= p && p < _n);
  33.         p += size;
  34.         for (int i = log; i >= 1; i--)
  35.             push(p >> i);
  36.         d[p] = x;
  37.         for (int i = 1; i <= log; i++)
  38.             update(p >> i);
  39.     }
  40.  
  41.     S get(int p)
  42.     {
  43.         assert(0 <= p && p < _n);
  44.         p += size;
  45.         for (int i = log; i >= 1; i--)
  46.             push(p >> i);
  47.         return d[p];
  48.     }
  49.  
  50.     S prod(int l, int r)
  51.     {
  52.         assert(0 <= l && l <= r && r <= _n);
  53.         if (l == r)
  54.             return e();
  55.  
  56.         l += size;
  57.         r += size;
  58.  
  59.         for (int i = log; i >= 1; i--) {
  60.             if (((l >> i) << i) != l)
  61.                 push(l >> i);
  62.             if (((r >> i) << i) != r)
  63.                 push((r - 1) >> i);
  64.         }
  65.  
  66.         S sml = e(), smr = e();
  67.         while (l < r) {
  68.             if (l & 1)
  69.                 sml = op(sml, d[l++]);
  70.             if (r & 1)
  71.                 smr = op(d[--r], smr);
  72.             l >>= 1;
  73.             r >>= 1;
  74.         }
  75.  
  76.         return op(sml, smr);
  77.     }
  78.  
  79.     S all_prod() { return d[1]; }
  80.  
  81.     void apply(int p, F f)
  82.     {
  83.         assert(0 <= p && p < _n);
  84.         p += size;
  85.         for (int i = log; i >= 1; i--)
  86.             push(p >> i);
  87.         d[p] = mapping(f, d[p]);
  88.         for (int i = 1; i <= log; i++)
  89.             update(p >> i);
  90.     }
  91.     void apply(int l, int r, F f)
  92.     {
  93.         assert(0 <= l && l <= r && r <= _n);
  94.         if (l == r)
  95.             return;
  96.  
  97.         l += size;
  98.         r += size;
  99.  
  100.         for (int i = log; i >= 1; i--) {
  101.             if (((l >> i) << i) != l)
  102.                 push(l >> i);
  103.             if (((r >> i) << i) != r)
  104.                 push((r - 1) >> i);
  105.         }
  106.  
  107.         {
  108.             int l2 = l, r2 = r;
  109.             while (l < r) {
  110.                 if (l & 1)
  111.                     all_apply(l++, f);
  112.                 if (r & 1)
  113.                     all_apply(--r, f);
  114.                 l >>= 1;
  115.                 r >>= 1;
  116.             }
  117.             l = l2;
  118.             r = r2;
  119.         }
  120.  
  121.         for (int i = 1; i <= log; i++) {
  122.             if (((l >> i) << i) != l)
  123.                 update(l >> i);
  124.             if (((r >> i) << i) != r)
  125.                 update((r - 1) >> i);
  126.         }
  127.     }
  128.  
  129.     template <bool (*g)(S)> int max_right(int l)
  130.     {
  131.         return max_right(l, [](S x) { return g(x); });
  132.     }
  133.     template <class G> int max_right(int l, G g)
  134.     {
  135.         assert(0 <= l && l <= _n);
  136.         assert(g(e()));
  137.         if (l == _n)
  138.             return _n;
  139.         l += size;
  140.         for (int i = log; i >= 1; i--)
  141.             push(l >> i);
  142.         S sm = e();
  143.         do {
  144.             while (l % 2 == 0)
  145.                 l >>= 1;
  146.             if (!g(op(sm, d[l]))) {
  147.                 while (l < size) {
  148.                     push(l);
  149.                     l = (2 * l);
  150.                     if (g(op(sm, d[l]))) {
  151.                         sm = op(sm, d[l]);
  152.                         l++;
  153.                     }
  154.                 }
  155.                 return l - size;
  156.             }
  157.             sm = op(sm, d[l]);
  158.             l++;
  159.         } while ((l & -l) != l);
  160.         return _n;
  161.     }
  162.  
  163.     template <bool (*g)(S)> int min_left(int r)
  164.     {
  165.         return min_left(r, [](S x) { return g(x); });
  166.     }
  167.     template <class G> int min_left(int r, G g)
  168.     {
  169.         assert(0 <= r && r <= _n);
  170.         assert(g(e()));
  171.         if (r == 0)
  172.             return 0;
  173.         r += size;
  174.         for (int i = log; i >= 1; i--)
  175.             push((r - 1) >> i);
  176.         S sm = e();
  177.         do {
  178.             r--;
  179.             while (r > 1 && (r % 2))
  180.                 r >>= 1;
  181.             if (!g(op(d[r], sm))) {
  182.                 while (r < size) {
  183.                     push(r);
  184.                     r = (2 * r + 1);
  185.                     if (g(op(d[r], sm))) {
  186.                         sm = op(d[r], sm);
  187.                         r--;
  188.                     }
  189.                 }
  190.                 return r + 1 - size;
  191.             }
  192.             sm = op(d[r], sm);
  193.         } while ((r & -r) != r);
  194.         return 0;
  195.     }
  196.  
  197.   private:
  198.     int _n, size, log;
  199.     std::vector<S> d;
  200.     std::vector<F> lz;
  201.  
  202.     void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
  203.     void all_apply(int k, F f)
  204.     {
  205.         d[k] = mapping(f, d[k]);
  206.         if (k < size)
  207.             lz[k] = composition(f, lz[k]);
  208.     }
  209.     void push(int k)
  210.     {
  211.         all_apply(2 * k, lz[k]);
  212.         all_apply(2 * k + 1, lz[k]);
  213.         lz[k] = id();
  214.     }
  215. };
  216.  
  217. } // namespace atcoder
  218.  
  219. using atcoder::lazy_segtree;
  220. using ll = long long;
  221.  
  222. struct S {
  223.     ll sum, n2sum, one[2];
  224. };
  225. struct F;
  226. F id();
  227. struct F {
  228.     ll op, fcnt, f0, f1;
  229.     // op 0 for element operation
  230.     // op 1 for n1 range flip
  231.     // op 2 for n2 range add
  232.     // op 3 for compound operators
  233.     S map(S r) {
  234.         switch(op) {
  235.             case 1:
  236.                 swap(r.one[0], r.one[1]);
  237.                 return r;
  238.             case 2:
  239.                 r.sum += r.one[1] * f1;
  240.                 return r;
  241.             case 3:
  242.                 r.sum += r.one[0] * f0 + r.one[1] * f1;
  243.                 if (fcnt % 2) swap(r.one[0], r.one[1]);
  244.                 return r;
  245.         }
  246.         return r;
  247.     }
  248.     F compose(F f) {
  249.         if (this->op == 0) return f;
  250.         if (f.op == 0) return *this;
  251.         if (f.op == 1 && this->op == 1) return id();
  252.         if (f.op == 2 && this->op == 2) {
  253.             this->f1 += f.f1;
  254.             return *this;
  255.         }
  256.         if (this->op == 1 && f.op == 2) return {3, 1, f.f1, f.f0};
  257.         if (this->op == 2 && f.op == 1) return {3, 1, f0, f1};
  258.        
  259.         F ret;
  260.         ret.op = 3;
  261.         ret.fcnt = (this->fcnt + f.fcnt) % 2;
  262.         ret.f0 = this->f0 + (fcnt % 2 ? f.f1 : f.f0);
  263.         ret.f1 = this->f1 + (fcnt % 2 ? f.f0 : f.f1);
  264.         return ret;
  265.     }
  266. };
  267. S e() { return {0, 0, {0, 0}}; }
  268. S op(S a, S b) { return {a.sum + b.sum, a.n2sum + b.n2sum, {a.one[0] + b.one[0], a.one[1] + b.one[1]}}; }
  269. S mapping(F f, S r) { return f.map(r); };
  270. F id() { return {0, 0, 0, 0}; };
  271. F composition(F f, F g) {
  272.     // g then f
  273.     return g.compose(f);
  274. };
  275.  
  276. class Solution {
  277. public:
  278.     vector<long long> handleQuery(vector<int>& ns1, vector<int>& ns2, vector<vector<int>>& qs) {
  279.         int n = ns1.size();
  280.         lazy_segtree<S, op, e, F, mapping, composition, id> seg(n);
  281.         for (int i = 0; i < n; ++i) {
  282.             seg.set(i, {ns2[i], ns2[i], {1 - ns1[i], ns1[i]}});
  283.         }
  284.         vector<ll> ret;
  285.  
  286.         for (const auto& q: qs) {
  287.             switch (q[0]) {
  288.                 case 1:
  289.                     seg.apply(q[1], q[2] + 1, F{1, 1, 0, 0});
  290.                     break;
  291.                 case 2:
  292.                     seg.apply(0, n, F{2, 0, 0, q[1]});
  293.                     break;
  294.                 case 3:
  295.                     auto ans = seg.all_prod();
  296.                     ret.push_back(ans.sum);
  297.                     break;
  298.             }
  299.         }
  300.         return ret;
  301.     }
  302. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement