Advertisement
pb_jiang

LC2569 AC

Feb 21st, 2023
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.20 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 ll = long long;
  220. using atcoder::lazy_segtree;
  221.  
  222. struct S {
  223.     ll sum, n2sum, one[2];
  224. };
  225. S op(S a, S b) { return S{a.sum + b.sum, a.n2sum + b.n2sum, {a.one[0] + b.one[0], a.one[1] + b.one[1]}}; }
  226. S e() { return {0, 0, {0, 0}}; }
  227.  
  228. struct F {
  229.     ll op, fcnt, f0, f1;
  230.     // 0: id
  231.     // 1: flip / add
  232. };
  233. S mapping(F f, S x)
  234. {
  235.     switch (f.op) {
  236.         case 0:
  237.             return x;
  238.         case 1:
  239.             // add then flip
  240.             x.sum = x.sum + f.f0 * x.one[0] + f.f1 * x.one[1];
  241.             if (f.fcnt)
  242.                 swap(x.one[0], x.one[1]);
  243.             return x;
  244.     }
  245.     return x;
  246. }
  247. F composition(F f, F g)
  248. {
  249.     // g then f
  250.     // f(g(x))
  251.     if (g.op == 0)
  252.         return f;
  253.     if (f.op == 0)
  254.         return g;
  255.  
  256.     F ret;
  257.     ret.op = 1;
  258.     ret.fcnt = (f.fcnt + g.fcnt) % 2;
  259.     ret.f0 = g.f0 + (g.fcnt == 0 ? f.f0 : f.f1);
  260.     ret.f1 = g.f1 + (g.fcnt == 0 ? f.f1 : f.f0);
  261.     return ret;
  262. }
  263. F id() { return {0, 0, 0, 0}; }
  264.  
  265. class Solution
  266. {
  267.   public:
  268.     vector<long long> handleQuery(vector<int> &nums1, vector<int> &nums2, vector<vector<int>> &queries)
  269.     {
  270.         int n = nums1.size();
  271.         lazy_segtree<S, op, e, F, mapping, composition, id> seg(n);
  272.         vector<ll> ret;
  273.         for (int i = 0; i < n; ++i)
  274.             seg.set(i, {nums2[i], nums2[i], {1 - nums1[i], nums1[i]}});
  275.         for (const auto &q : queries) {
  276.             switch (q[0]) {
  277.                 case 1: {
  278.                     int l = q[1], r = q[2] + 1;
  279.                     seg.apply(l, r, F{1, 1, 0, 0});
  280.                     break;
  281.                 }
  282.                 case 2:
  283.                     seg.apply(0, n, F{1, 0, 0, q[1]});
  284.                     break;
  285.                 case 3:
  286.                     auto node = seg.all_prod();
  287.                     ret.push_back(node.sum);
  288.                     break;
  289.             }
  290.         }
  291.         return ret;
  292.     }
  293. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement