Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Problem: P2572 [SCOI2010] 序列操作
- // Contest: Luogu
- // URL: https://www.luogu.com.cn/problem/P2572
- // Memory Limit: 128 MB
- // Time Limit: 1000 ms
- //
- // Powered by CP Editor (https://cpeditor.org)
- #include <assert.h>
- #include <bits/stdc++.h>
- using namespace std;
- #define dbg(...) logger(#__VA_ARGS__, __VA_ARGS__)
- template <typename... Args> void logger(string vars, Args &&... values)
- {
- cerr << vars << " = ";
- string delim = "";
- (..., (cerr << delim << values, delim = ", "));
- cerr << endl;
- }
- namespace atcoder
- {
- template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S), F (*composition)(F, F), F (*id)()>
- struct lazy_segtree {
- int ceil_pow2(int n)
- {
- int x = 0;
- while ((1U << x) < (unsigned int) (n))
- x++;
- return x;
- }
- public:
- lazy_segtree() : lazy_segtree(0) {}
- explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
- explicit lazy_segtree(const std::vector<S> &v) : _n(int(v.size()))
- {
- log = ceil_pow2(_n);
- size = 1 << log;
- d = std::vector<S>(2 * size, e());
- lz = std::vector<F>(size, id());
- for (int i = 0; i < _n; i++)
- d[size + i] = v[i];
- for (int i = size - 1; i >= 1; i--) {
- update(i);
- }
- }
- void set(int p, S x)
- {
- assert(0 <= p && p < _n);
- p += size;
- for (int i = log; i >= 1; i--)
- push(p >> i);
- d[p] = x;
- for (int i = 1; i <= log; i++)
- update(p >> i);
- }
- S get(int p)
- {
- assert(0 <= p && p < _n);
- p += size;
- for (int i = log; i >= 1; i--)
- push(p >> i);
- return d[p];
- }
- S prod(int l, int r)
- {
- assert(0 <= l && l <= r && r <= _n);
- if (l == r)
- return e();
- l += size;
- r += size;
- for (int i = log; i >= 1; i--) {
- if (((l >> i) << i) != l)
- push(l >> i);
- if (((r >> i) << i) != r)
- push((r - 1) >> i);
- }
- S sml = e(), smr = e();
- while (l < r) {
- if (l & 1)
- sml = op(sml, d[l++]);
- if (r & 1)
- smr = op(d[--r], smr);
- l >>= 1;
- r >>= 1;
- }
- return op(sml, smr);
- }
- S all_prod() { return d[1]; }
- void apply(int p, F f)
- {
- assert(0 <= p && p < _n);
- p += size;
- for (int i = log; i >= 1; i--)
- push(p >> i);
- d[p] = mapping(f, d[p]);
- for (int i = 1; i <= log; i++)
- update(p >> i);
- }
- void apply(int l, int r, F f)
- {
- assert(0 <= l && l <= r && r <= _n);
- if (l == r)
- return;
- l += size;
- r += size;
- for (int i = log; i >= 1; i--) {
- if (((l >> i) << i) != l)
- push(l >> i);
- if (((r >> i) << i) != r)
- push((r - 1) >> i);
- }
- {
- int l2 = l, r2 = r;
- while (l < r) {
- if (l & 1)
- all_apply(l++, f);
- if (r & 1)
- all_apply(--r, f);
- l >>= 1;
- r >>= 1;
- }
- l = l2;
- r = r2;
- }
- for (int i = 1; i <= log; i++) {
- if (((l >> i) << i) != l)
- update(l >> i);
- if (((r >> i) << i) != r)
- update((r - 1) >> i);
- }
- }
- template <bool (*g)(S)> int max_right(int l)
- {
- return max_right(l, [](S x) { return g(x); });
- }
- template <class G> int max_right(int l, G g)
- {
- assert(0 <= l && l <= _n);
- assert(g(e()));
- if (l == _n)
- return _n;
- l += size;
- for (int i = log; i >= 1; i--)
- push(l >> i);
- S sm = e();
- do {
- while (l % 2 == 0)
- l >>= 1;
- if (!g(op(sm, d[l]))) {
- while (l < size) {
- push(l);
- l = (2 * l);
- if (g(op(sm, d[l]))) {
- sm = op(sm, d[l]);
- l++;
- }
- }
- return l - size;
- }
- sm = op(sm, d[l]);
- l++;
- } while ((l & -l) != l);
- return _n;
- }
- template <bool (*g)(S)> int min_left(int r)
- {
- return min_left(r, [](S x) { return g(x); });
- }
- template <class G> int min_left(int r, G g)
- {
- assert(0 <= r && r <= _n);
- assert(g(e()));
- if (r == 0)
- return 0;
- r += size;
- for (int i = log; i >= 1; i--)
- push((r - 1) >> i);
- S sm = e();
- do {
- r--;
- while (r > 1 && (r % 2))
- r >>= 1;
- if (!g(op(d[r], sm))) {
- while (r < size) {
- push(r);
- r = (2 * r + 1);
- if (g(op(d[r], sm))) {
- sm = op(d[r], sm);
- r--;
- }
- }
- return r + 1 - size;
- }
- sm = op(d[r], sm);
- } while ((r & -r) != r);
- return 0;
- }
- private:
- int _n, size, log;
- std::vector<S> d;
- std::vector<F> lz;
- void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
- void all_apply(int k, F f)
- {
- d[k] = mapping(f, d[k]);
- if (k < size)
- lz[k] = composition(f, lz[k]);
- }
- void push(int k)
- {
- all_apply(2 * k, lz[k]);
- all_apply(2 * k + 1, lz[k]);
- lz[k] = id();
- }
- };
- } // namespace atcoder
- template <class T> using mpq = priority_queue<T, vector<T>, greater<T>>;
- using ll = long long;
- using pii = pair<int, int>;
- using atcoder::lazy_segtree;
- int n, m;
- struct S {
- int ele_cnt, sum_val;
- int max_conseq1, lmargin1, rmargin1, nz;
- int max_conseq0, lmargin0, rmargin0, no;
- };
- struct F {
- int op; // 0: set 0; 1: set 1; 2: set negative; 3: remain
- };
- S op(S a, S b)
- {
- S ret;
- ret.ele_cnt = a.ele_cnt + b.ele_cnt;
- ret.sum_val = a.sum_val + b.sum_val;
- ret.max_conseq1 = max(a.max_conseq1, b.max_conseq1);
- ret.lmargin1 = a.lmargin1;
- ret.rmargin1 = b.rmargin1;
- ret.nz = a.nz && b.nz;
- ret.max_conseq0 = max(a.max_conseq0, b.max_conseq0);
- ret.lmargin0 = a.lmargin0;
- ret.rmargin0 = b.rmargin0;
- ret.no = a.no && b.no;
- if (a.nz)
- ret.lmargin1 = a.lmargin1 + b.lmargin1;
- if (b.nz)
- ret.rmargin1 = a.rmargin1 + b.rmargin1;
- ret.max_conseq1 = max(ret.max_conseq1, a.rmargin1 + b.lmargin1);
- if (a.no)
- ret.lmargin0 = a.lmargin0 + b.lmargin0;
- if (b.no)
- ret.rmargin0 = a.rmargin0 + b.lmargin0;
- ret.max_conseq0 = max(ret.max_conseq0, a.rmargin0 + b.lmargin0);
- return ret;
- }
- S e() { return S{0, 0, 0, 0, 0, 0}; }
- S mapping(F f, S r)
- {
- switch (f.op) {
- case 0:
- return S{
- r.ele_cnt, 0, 0, 0, 0, 0, r.ele_cnt, r.ele_cnt, r.ele_cnt, 1,
- };
- case 1:
- return S{
- r.ele_cnt, r.ele_cnt, r.ele_cnt, r.ele_cnt, r.ele_cnt, 1, 0, 0, 0, 0,
- };
- case 2:
- return S{
- r.ele_cnt, r.ele_cnt - r.sum_val, r.max_conseq0, r.lmargin0, r.rmargin0,
- r.no, r.max_conseq1, r.lmargin1, r.rmargin1, r.nz,
- };
- case 3:
- return r;
- }
- return r;
- }
- F id() { return F{3}; }
- F composition(F f, F g)
- {
- if (f.op == 3)
- return g;
- if (f.op == 0 || f.op == 1)
- return f;
- // f.op == 2
- if (g.op == 0 || g.op == 1)
- return F{1 - g.op};
- if (g.op == 2)
- return id();
- return f;
- }
- int main(int argc, char **argv)
- {
- scanf("%d%d", &n, &m);
- vector<int> arr(n);
- for (int i = 0; i < n; ++i)
- scanf("%d", &arr[i]);
- lazy_segtree<S, op, e, F, mapping, composition, id> seg(n);
- for (int i = 0; i < n; ++i)
- if (arr[i])
- seg.set(i, S{1, 1, 1, 1, 1, 1, 0, 0, 0, 0});
- else
- seg.set(i, S{1, 0, 0, 0, 0, 0, 1, 1, 1, 1});
- for (int i = 0; i < m; ++i) {
- int cmd, l, r;
- scanf("%d%d%d", &cmd, &l, &r);
- S ans;
- switch (cmd) {
- case 0:
- seg.apply(l, r + 1, F{0});
- break;
- case 1:
- seg.apply(l, r + 1, F{1});
- break;
- case 2:
- seg.apply(l, r + 1, F{2});
- break;
- case 3:
- ans = seg.prod(l, r + 1);
- printf("%d\n", ans.sum_val);
- break;
- case 4:
- ans = seg.prod(l, r + 1);
- printf("%d\n", ans.max_conseq1);
- break;
- }
- }
- return 0;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement