stripe_python @ 2024-07-14 11:45:24
#include <bits/stdc++.h>
using namespace std;
#define N 100005
class SegmentTree {
#define ls (rt << 1)
#define rs (rt << 1 | 1)
private:
int n, hot;
int sum[N << 4], maxc[2][N << 4], lmax[2][N << 4], rmax[2][N << 4];
int cover[N << 4], rev[N << 4];
inline void pushup(int rt, int ln, int rn, int lss = -1, int rss = -1) {
lss = (lss == -1) ? ls : lss, rss = (rss == -1) ? rs : rss;
sum[rt] = sum[lss] + sum[rss];
for (int i = 0; i <= 1; i++) {
lmax[i][rt] = lmax[i][lss];
if (i == 1 && sum[lss] == ln) lmax[i][rt] += lmax[i][rss];
else if (i == 0 && sum[lss] == 0) lmax[i][rt] += lmax[i][rss];
rmax[i][rt] = rmax[i][rss];
if (i == 1 && sum[rss] == rn) rmax[i][rt] += rmax[i][lss];
else if (i == 0 && sum[rss] == 0) rmax[i][rt] += rmax[i][lss];
maxc[i][rt] = max(rmax[i][lss] + lmax[i][rss], max(maxc[i][lss], maxc[i][rss]));
}
}
inline void pushdown(int rt, int ln, int rn) {
if (cover[rt] != -1) {
int val = cover[rt];
rev[rt] = 0, cover[rt] = -1;
sum[ls] = val * ln, sum[rs] = val * rn;
cover[ls] = cover[rs] = val, rev[ls] = rev[rs] = 0;
maxc[val][ls] = lmax[val][ls] = rmax[val][ls] = ln;
maxc[val ^ 1][ls] = lmax[val ^ 1][ls] = rmax[val ^ 1][ls] = 0;
maxc[val][rs] = lmax[val][rs] = rmax[val][rs] = rn;
maxc[val ^ 1][rs] = lmax[val ^ 1][rs] = rmax[val ^ 1][rs] = 0;
}
if (rev[rt]) {
sum[ls] = ln - sum[ls], sum[rs] = rn - sum[rs];
if (cover[ls] != -1) cover[ls] ^= 1;
else rev[ls] ^= 1;
if (cover[rs] != -1) cover[rs] ^= 1;
else rev[rs] ^= 1;
swap(maxc[0][ls], maxc[1][ls]), swap(lmax[0][ls], lmax[1][ls]),
swap(rmax[0][ls], rmax[1][ls]);
swap(maxc[0][rs], maxc[1][rs]), swap(lmax[0][rs], lmax[1][rs]),
swap(rmax[0][rs], rmax[1][rs]);
rev[rt] ^= 1;
}
}
void build(const int* a, int l, int r, int rt) {
if (l == r) {
sum[rt] = a[l];
maxc[0][rt] = lmax[0][rt] = rmax[0][rt] = (a[l] == 0);
maxc[1][rt] = lmax[1][rt] = rmax[1][rt] = (a[l] == 1);
return;
}
int mid = (l + r) >> 1;
build(a, l, mid, ls), build(a, mid + 1, r, rs);
pushup(rt, mid - l + 1, r - mid);
}
void update(int tl, int tr, const int& c, int l, int r, int rt) {
if (tl <= l && r <= tr) {
sum[rt] = (r - l + 1) * c, cover[rt] = c;
maxc[c][rt] = lmax[c][rt] = rmax[c][rt] = r - l + 1;
maxc[c ^ 1][rt] = lmax[c ^ 1][rt] = rmax[c ^ 1][rt] = 0;
return;
}
int mid = (l + r) >> 1;
pushdown(rt, mid - l + 1, r - mid);
if (tl <= mid) update(tl, tr, c, l, mid, ls);
if (tr > mid) update(tl, tr, c, mid + 1, r, rs);
pushup(rt, mid - l + 1, r - mid);
}
void reverse(int tl, int tr, int l, int r, int rt) {
if (tl <= l && r <= tr) {
sum[rt] = r - l + 1 - sum[rt], rev[rt] ^= 1;
swap(maxc[0][rt], maxc[1][rt]), swap(lmax[0][rt], lmax[1][rt]),
swap(rmax[0][rt], rmax[1][rt]);
return;
}
int mid = (l + r) >> 1;
pushdown(rt, mid - l + 1, r - mid);
if (tl <= mid) reverse(tl, tr, l, mid, ls);
if (tr > mid) reverse(tl, tr, mid + 1, r, rs);
pushup(rt, mid - l + 1, r - mid);
}
int query_sum(int tl, int tr, int l, int r, int rt) {
if (tl <= l && r <= tr) return sum[rt];
int mid = (l + r) >> 1, res = 0;
pushdown(rt, mid - l + 1, r - mid);
if (tl <= mid) res += query_sum(tl, tr, l, mid, ls);
if (tr > mid) res += query_sum(tl, tr, mid + 1, r, rs);
return res;
}
int query_max(int tl, int tr, int l, int r, int rt) {
if (tl <= l && r <= tr) return rt;
int mid = (l + r) >> 1;
pushdown(rt, mid - l + 1, r - mid);
if (tl <= mid) return query_max(tl, tr, l, mid, ls);
if (tr > mid) return query_max(tl, tr, mid + 1, r, rs);
int ln = query_max(tl, tr, l, mid, ls), rn = query_max(tl, tr, mid + 1, r, rs), res = ++hot;
pushup(res, mid - l + 1, r - mid, ln, rn);
return res;
}
public:
SegmentTree(int _n) : n(_n), hot(_n << 2) {}
SegmentTree(const int* a, int _n) : n(_n), hot(_n << 2) {build(a, 1, n, 1);}
void update(int l, int r, const int& c) {update(l, r, c, 1, n, 1);}
void reverse(int l, int r) {reverse(l, r, 1, n, 1);}
int query_sum(int l, int r) {return query_sum(l, r, 1, n, 1);}
int query_max(int l, int r, const int& c) {
int res = maxc[c][query_max(l, r, 1, n, 1)];
return hot = (n << 2), res;
}
#undef ls
#undef rs
};
int n, q, a[N], opt, l, r;
void _main() {
cin >> n >> q;
for (int i = 1; i <= n; i++) cin >> a[i];
SegmentTree sgt(a, n);
while (q--) {
cin >> opt >> l >> r;
l++, r++;
if (opt == 0) sgt.update(l, r, 0);
else if (opt == 1) sgt.update(l, r, 1);
else if (opt == 2) sgt.reverse(l, r);
else if (opt == 3) cout << sgt.query_sum(l, r) << '\n';
else if (opt == 4) cout << sgt.query_max(l, r, 1) << '\n';
}
} signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
#ifndef ONLINE_JUDGE
#ifndef SPN_LOCAL
freopen(".in", "r", stdin), freopen(".out", "w", stdout);
#endif
#endif
int t = 1;
// cin >> t;
while (t--) _main();
return 0;
}