SillyBilly @ 2023-10-16 13:43:53
#include<bits/stdc++.h>
using namespace std;
const int maxN = 1e5 + 10;
struct Node {
int len, l0, l1, cnt, lmax0, rmax0, lmax1, rmax1;
Node() { len = l0 = l1 = cnt = 0; lmax0 = lmax1 = rmax0 = rmax1 = 0; }
Node operator + (const Node& rhs) {
if(len == 0) return rhs;
Node res;
res.cnt = cnt + rhs.cnt; res.len = len + rhs.len;
if(lmax0 == len) res.lmax0 = lmax0 + rhs.lmax0;
else res.lmax0 = lmax0;
if(rhs.rmax0 == rhs.len) res.rmax0 = rmax0 + rhs.rmax0;
else res.rmax0 = rhs.rmax0;
if(lmax1 == len) res.lmax1 = lmax1 + rhs.lmax1;
else res.lmax1 = lmax1;
if(rhs.rmax1 == rhs.len) res.rmax1 = rmax1 + rhs.rmax1;
else res.rmax1 = rhs.rmax1;
res.l0 = max(l0, rhs.l0);
res.l0 = max(res.l0, rmax0 + rhs.lmax0);
res.l1 = max(l1, rhs.l1);
res.l1 = max(res.l1, rmax1 + rhs.lmax1);
return res;
}
void cover(int x) {
if(x) {
l0 = 0, l1 = cnt = len;
lmax0 = rmax0 = 0;
lmax1 = rmax1 = len;
} else {
l0 = len, l1 = cnt = 0;
lmax0 = rmax0 = len;
lmax1 = rmax1 = 0;
}
}
void reverse() {
cnt = len - cnt;
swap(l0, l1); swap(lmax0, lmax1), swap(rmax0, rmax1);
}
Node operator += (const Node& rhs) {
return *this = *this + rhs;
}
} nodes[maxN << 2];
struct SegTree {
#define ls p << 1
#define rs p << 1 | 1
#define mid ((l + r) >> 1)
int a[maxN], tag1[maxN], tag2[maxN];
void pushup(int p) { nodes[p] = nodes[ls] + nodes[rs]; }
void build(int p, int l, int r) {
tag1[p] = -1, tag2[p] = 0;
if(l == r) {
nodes[p].len = 1;
return nodes[p].cover(a[l]);
}
build(ls, l, mid), build(rs, mid + 1, r);
pushup(p);
}
void pushdown(int p) {
if(~tag1[p]) {
nodes[ls].cover(tag1[p]), nodes[rs].cover(tag1[p]);
tag1[p] = -1;
}
if(tag2[p]) {
nodes[ls].reverse(), nodes[rs].reverse();
tag2[p] = 0;
}
}
void cover(int p, int l, int r, int nl, int nr, int val) {
if(nl <= l && r <= nr) {
tag1[p] = val;
return nodes[p].cover(val);
}
pushdown(p);
if(nl <= mid) cover(ls, l, mid, nl, nr, val);
if(nr > mid) cover(rs, mid + 1, r, nl, nr, val);
pushup(p);
}
void reverse(int p, int l, int r, int nl, int nr) {
if(nl <= l && r <= nr) {
tag2[p] = !tag2[p];
return nodes[p].reverse();
}
pushdown(p);
if(nl <= mid) reverse(ls, l, mid, nl, nr);
if(nr > mid) reverse(rs, mid + 1, r, nl, nr);
pushup(p);
}
Node query(int p, int l, int r, int nl, int nr) {
if(nl <= l && r <= nr) return nodes[p];
pushdown(p);
Node res;
if(nl <= mid) res += query(ls, l, mid, nl, nr);
if(nr > mid) res += query(rs, mid + 1, r, nl, nr);
pushup(p);
return res;
}
} tree;
int main() {
int n, m; cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> tree.a[i];
tree.build(1, 1, n);
while(m-- > 0) {
int op, l, r; cin >> op >> l >> r; l++, r++;
if(op == 0) tree.cover(1, 1, n, l, r, 0);
if(op == 1) tree.cover(1, 1, n, l, r, 1);
if(op == 2) tree.reverse(1, 1, n, l, r);
if(op == 3) cout << tree.query(1, 1, n, l, r).cnt << "\n";
if(op == 4) cout << tree.query(1, 1, n, l, r).l1 << "\n";
}
}