Advertisement
pb_jiang

luogu P2572 - lazysegtree

Sep 13th, 2022 (edited)
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.05 KB | None | 0 0
  1. // Problem: P2572 [SCOI2010] 序列操作
  2. // Contest: Luogu
  3. // URL: https://www.luogu.com.cn/problem/P2572
  4. // Memory Limit: 128 MB
  5. // Time Limit: 1000 ms
  6. //
  7. // Powered by CP Editor (https://cpeditor.org)
  8.  
  9. #include <assert.h>
  10. #include <bits/stdc++.h>
  11. using namespace std;
  12. #define dbg(...) logger(#__VA_ARGS__, __VA_ARGS__)
  13. template <typename... Args> void logger(string vars, Args &&... values)
  14. {
  15.     cerr << vars << " = ";
  16.     string delim = "";
  17.     (..., (cerr << delim << values, delim = ", "));
  18.     cerr << endl;
  19. }
  20.  
  21. namespace atcoder
  22. {
  23.  
  24. template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S), F (*composition)(F, F), F (*id)()>
  25. struct lazy_segtree {
  26.     int ceil_pow2(int n)
  27.     {
  28.         int x = 0;
  29.         while ((1U << x) < (unsigned int) (n))
  30.             x++;
  31.         return x;
  32.     }
  33.  
  34.   public:
  35.     lazy_segtree() : lazy_segtree(0) {}
  36.     explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
  37.     explicit lazy_segtree(const std::vector<S> &v) : _n(int(v.size()))
  38.     {
  39.         log = ceil_pow2(_n);
  40.         size = 1 << log;
  41.         d = std::vector<S>(2 * size, e());
  42.         lz = std::vector<F>(size, id());
  43.         for (int i = 0; i < _n; i++)
  44.             d[size + i] = v[i];
  45.         for (int i = size - 1; i >= 1; i--) {
  46.             update(i);
  47.         }
  48.     }
  49.  
  50.     void set(int p, S x)
  51.     {
  52.         assert(0 <= p && p < _n);
  53.         p += size;
  54.         for (int i = log; i >= 1; i--)
  55.             push(p >> i);
  56.         d[p] = x;
  57.         for (int i = 1; i <= log; i++)
  58.             update(p >> i);
  59.     }
  60.  
  61.     S get(int p)
  62.     {
  63.         assert(0 <= p && p < _n);
  64.         p += size;
  65.         for (int i = log; i >= 1; i--)
  66.             push(p >> i);
  67.         return d[p];
  68.     }
  69.  
  70.     S prod(int l, int r)
  71.     {
  72.         assert(0 <= l && l <= r && r <= _n);
  73.         if (l == r)
  74.             return e();
  75.  
  76.         l += size;
  77.         r += size;
  78.  
  79.         for (int i = log; i >= 1; i--) {
  80.             if (((l >> i) << i) != l)
  81.                 push(l >> i);
  82.             if (((r >> i) << i) != r)
  83.                 push((r - 1) >> i);
  84.         }
  85.  
  86.         S sml = e(), smr = e();
  87.         while (l < r) {
  88.             if (l & 1)
  89.                 sml = op(sml, d[l++]);
  90.             if (r & 1)
  91.                 smr = op(d[--r], smr);
  92.             l >>= 1;
  93.             r >>= 1;
  94.         }
  95.  
  96.         return op(sml, smr);
  97.     }
  98.  
  99.     S all_prod() { return d[1]; }
  100.  
  101.     void apply(int p, F f)
  102.     {
  103.         assert(0 <= p && p < _n);
  104.         p += size;
  105.         for (int i = log; i >= 1; i--)
  106.             push(p >> i);
  107.         d[p] = mapping(f, d[p]);
  108.         for (int i = 1; i <= log; i++)
  109.             update(p >> i);
  110.     }
  111.     void apply(int l, int r, F f)
  112.     {
  113.         assert(0 <= l && l <= r && r <= _n);
  114.         if (l == r)
  115.             return;
  116.  
  117.         l += size;
  118.         r += size;
  119.  
  120.         for (int i = log; i >= 1; i--) {
  121.             if (((l >> i) << i) != l)
  122.                 push(l >> i);
  123.             if (((r >> i) << i) != r)
  124.                 push((r - 1) >> i);
  125.         }
  126.  
  127.         {
  128.             int l2 = l, r2 = r;
  129.             while (l < r) {
  130.                 if (l & 1)
  131.                     all_apply(l++, f);
  132.                 if (r & 1)
  133.                     all_apply(--r, f);
  134.                 l >>= 1;
  135.                 r >>= 1;
  136.             }
  137.             l = l2;
  138.             r = r2;
  139.         }
  140.  
  141.         for (int i = 1; i <= log; i++) {
  142.             if (((l >> i) << i) != l)
  143.                 update(l >> i);
  144.             if (((r >> i) << i) != r)
  145.                 update((r - 1) >> i);
  146.         }
  147.     }
  148.  
  149.     template <bool (*g)(S)> int max_right(int l)
  150.     {
  151.         return max_right(l, [](S x) { return g(x); });
  152.     }
  153.     template <class G> int max_right(int l, G g)
  154.     {
  155.         assert(0 <= l && l <= _n);
  156.         assert(g(e()));
  157.         if (l == _n)
  158.             return _n;
  159.         l += size;
  160.         for (int i = log; i >= 1; i--)
  161.             push(l >> i);
  162.         S sm = e();
  163.         do {
  164.             while (l % 2 == 0)
  165.                 l >>= 1;
  166.             if (!g(op(sm, d[l]))) {
  167.                 while (l < size) {
  168.                     push(l);
  169.                     l = (2 * l);
  170.                     if (g(op(sm, d[l]))) {
  171.                         sm = op(sm, d[l]);
  172.                         l++;
  173.                     }
  174.                 }
  175.                 return l - size;
  176.             }
  177.             sm = op(sm, d[l]);
  178.             l++;
  179.         } while ((l & -l) != l);
  180.         return _n;
  181.     }
  182.  
  183.     template <bool (*g)(S)> int min_left(int r)
  184.     {
  185.         return min_left(r, [](S x) { return g(x); });
  186.     }
  187.     template <class G> int min_left(int r, G g)
  188.     {
  189.         assert(0 <= r && r <= _n);
  190.         assert(g(e()));
  191.         if (r == 0)
  192.             return 0;
  193.         r += size;
  194.         for (int i = log; i >= 1; i--)
  195.             push((r - 1) >> i);
  196.         S sm = e();
  197.         do {
  198.             r--;
  199.             while (r > 1 && (r % 2))
  200.                 r >>= 1;
  201.             if (!g(op(d[r], sm))) {
  202.                 while (r < size) {
  203.                     push(r);
  204.                     r = (2 * r + 1);
  205.                     if (g(op(d[r], sm))) {
  206.                         sm = op(d[r], sm);
  207.                         r--;
  208.                     }
  209.                 }
  210.                 return r + 1 - size;
  211.             }
  212.             sm = op(d[r], sm);
  213.         } while ((r & -r) != r);
  214.         return 0;
  215.     }
  216.  
  217.   private:
  218.     int _n, size, log;
  219.     std::vector<S> d;
  220.     std::vector<F> lz;
  221.  
  222.     void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
  223.     void all_apply(int k, F f)
  224.     {
  225.         d[k] = mapping(f, d[k]);
  226.         if (k < size)
  227.             lz[k] = composition(f, lz[k]);
  228.     }
  229.     void push(int k)
  230.     {
  231.         all_apply(2 * k, lz[k]);
  232.         all_apply(2 * k + 1, lz[k]);
  233.         lz[k] = id();
  234.     }
  235. };
  236.  
  237. } // namespace atcoder
  238.  
  239. template <class T> using mpq = priority_queue<T, vector<T>, greater<T>>;
  240. using ll = long long;
  241. using pii = pair<int, int>;
  242. using atcoder::lazy_segtree;
  243. int n, m;
  244.  
  245. struct S {
  246.     int ele_cnt, sum_val;
  247.     int max_conseq1, lmargin1, rmargin1, nz;
  248.     int max_conseq0, lmargin0, rmargin0, no;
  249. };
  250. struct F {
  251.     int op; // 0: set 0; 1: set 1; 2: set negative; 3: remain
  252. };
  253. S op(S a, S b)
  254. {
  255.  
  256.     S ret;
  257.     ret.ele_cnt = a.ele_cnt + b.ele_cnt;
  258.     ret.sum_val = a.sum_val + b.sum_val;
  259.  
  260.     ret.max_conseq1 = max(a.max_conseq1, b.max_conseq1);
  261.     ret.lmargin1 = a.lmargin1;
  262.     ret.rmargin1 = b.rmargin1;
  263.     ret.nz = a.nz && b.nz;
  264.  
  265.     ret.max_conseq0 = max(a.max_conseq0, b.max_conseq0);
  266.     ret.lmargin0 = a.lmargin0;
  267.     ret.rmargin0 = b.rmargin0;
  268.     ret.no = a.no && b.no;
  269.  
  270.     if (a.nz)
  271.         ret.lmargin1 = a.lmargin1 + b.lmargin1;
  272.     if (b.nz)
  273.         ret.rmargin1 = a.rmargin1 + b.rmargin1;
  274.     ret.max_conseq1 = max(ret.max_conseq1, a.rmargin1 + b.lmargin1);
  275.  
  276.     if (a.no)
  277.         ret.lmargin0 = a.lmargin0 + b.lmargin0;
  278.     if (b.no)
  279.         ret.rmargin0 = a.rmargin0 + b.lmargin0;
  280.     ret.max_conseq0 = max(ret.max_conseq0, a.rmargin0 + b.lmargin0);
  281.  
  282.     return ret;
  283. }
  284. S e() { return S{0, 0, 0, 0, 0, 0}; }
  285. S mapping(F f, S r)
  286. {
  287.     switch (f.op) {
  288.         case 0:
  289.             return S{
  290.                 r.ele_cnt, 0, 0, 0, 0, 0, r.ele_cnt, r.ele_cnt, r.ele_cnt, 1,
  291.             };
  292.         case 1:
  293.             return S{
  294.                 r.ele_cnt, r.ele_cnt, r.ele_cnt, r.ele_cnt, r.ele_cnt, 1, 0, 0, 0, 0,
  295.             };
  296.         case 2:
  297.             return S{
  298.                 r.ele_cnt, r.ele_cnt - r.sum_val, r.max_conseq0, r.lmargin0, r.rmargin0,
  299.                 r.no,      r.max_conseq1,         r.lmargin1,    r.rmargin1, r.nz,
  300.             };
  301.         case 3:
  302.             return r;
  303.     }
  304.     return r;
  305. }
  306. F id() { return F{3}; }
  307. F composition(F f, F g)
  308. {
  309.     if (f.op == 3)
  310.         return g;
  311.     if (f.op == 0 || f.op == 1)
  312.         return f;
  313.  
  314.     // f.op == 2
  315.     if (g.op == 0 || g.op == 1)
  316.         return F{1 - g.op};
  317.     if (g.op == 2)
  318.         return id();
  319.     return f;
  320. }
  321.  
  322.  
  323. int main(int argc, char **argv)
  324. {
  325.     scanf("%d%d", &n, &m);
  326.     vector<int> arr(n);
  327.     for (int i = 0; i < n; ++i)
  328.         scanf("%d", &arr[i]);
  329.     lazy_segtree<S, op, e, F, mapping, composition, id> seg(n);
  330.     for (int i = 0; i < n; ++i)
  331.         if (arr[i])
  332.             seg.set(i, S{1, 1, 1, 1, 1, 1, 0, 0, 0, 0});
  333.         else
  334.             seg.set(i, S{1, 0, 0, 0, 0, 0, 1, 1, 1, 1});
  335.     for (int i = 0; i < m; ++i) {
  336.         int cmd, l, r;
  337.         scanf("%d%d%d", &cmd, &l, &r);
  338.         S ans;
  339.         switch (cmd) {
  340.             case 0:
  341.                 seg.apply(l, r + 1, F{0});
  342.                 break;
  343.             case 1:
  344.                 seg.apply(l, r + 1, F{1});
  345.                 break;
  346.             case 2:
  347.                 seg.apply(l, r + 1, F{2});
  348.                 break;
  349.             case 3:
  350.                 ans = seg.prod(l, r + 1);
  351.                 printf("%d\n", ans.sum_val);
  352.                 break;
  353.             case 4:
  354.                 ans = seg.prod(l, r + 1);
  355.                 printf("%d\n", ans.max_conseq1);
  356.                 break;
  357.         }
  358.     }
  359.     return 0;
  360. };
  361.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement