#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
int read() {
int v = 0, f = 1;
char c = getchar();
while (c < '0' || '9' < c) {
if (c == '-')
f = -1;
c = getchar();
}
while ('0' <= c && c <= '9') {
v = v * 10 + c - '0';
c = getchar();
}
return v * f;
}
const int N = 1e5 + 5;
int n, m, val[N];
struct Node {
int l, r, ls, rs;
int v, l0, l1, r0, r1, c0, c1, t;
void pushup(const Node &x, const Node &y) {
v = x.v + y.v;
l0 = x.l0, l1 = x.l1;
if (x.v == 0)
l0 = x.r - x.l + 1 + y.l0;
else if (x.v == x.r - x.l + 1)
l1 = x.r - x.l + 1 + y.l1;
r0 = y.r0, r1 = y.r1;
if (y.v == 0)
r0 = x.r0 + y.r - y.l + 1;
else if (y.v == y.r - y.l + 1)
r1 = x.r1 + y.r - y.l + 1;
c0 = max(x.r0 + y.l0, max(x.c0, y.c0));
c1 = max(x.r1 + y.l1, max(x.c1, y.c1));
}
void apply(int k) {
t = k;
if (k == 0) {
v = 0;
l0 = r0 = c0 = r - l + 1;
l1 = r1 = c1 = 0;
} else if (k == 1) {
v = r - l + 1;
l0 = r0 = c0 = 0;
l1 = r1 = c1 = r - l + 1;
} else {
v = r - l + 1 - v;
swap(l0, l1);
swap(r0, r1);
swap(c0, c1);
}
}
};
vector<Node> tr;
int rt;
void pushdown(int p) {
int &k = tr[p].t;
if (~k) {
tr[tr[p].ls].apply(k);
tr[tr[p].rs].apply(k);
k = -1;
}
}
void debug() {
fprintf(stderr, "==========\n");
for (int i = 0; i < tr.size(); i++) {
fprintf(stderr,
"%d:l=%d,r=%d,ls=%d,rs=%d,v=%d,l0=%d,l1=%d,r0=%d,r1=%d,"
"c0=%d,c1=%d,t=%d\n",
i, tr[i].l, tr[i].r, tr[i].ls, tr[i].rs, tr[i].v, tr[i].l0,
tr[i].l1, tr[i].r0, tr[i].r1, tr[i].c0, tr[i].c1, tr[i].t);
}
}
int build(int l, int r) {
int p = tr.size();
tr.push_back(Node());
tr[p].l = l, tr[p].r = r, tr[p].t = -1;
if (l == r) {
tr[p].v = val[l];
if (val[l] == 0) {
tr[p].l0 = tr[p].r0 = tr[p].c0 = 1;
tr[p].l1 = tr[p].r1 = tr[p].c1 = 0;
} else {
tr[p].l0 = tr[p].r0 = tr[p].c0 = 0;
tr[p].l1 = tr[p].r1 = tr[p].c1 = 1;
}
return p;
}
int mid = (l + r) >> 1;
tr[p].ls = build(l, mid);
tr[p].rs = build(mid + 1, r);
tr[p].pushup(tr[tr[p].ls], tr[tr[p].rs]);
return p;
}
void update(int p, int x, int y, int k) {
int l = tr[p].l, r = tr[p].r;
// fprintf(stderr, "UPDATE %d %d %d %d %d %d\n", p, l, r, x, y, k);
if (x <= l && r <= y) {
tr[p].apply(k);
return;
}
pushdown(p);
int mid = (l + r) >> 1;
if (x <= mid)
update(tr[p].ls, x, y, k);
if (mid < y)
update(tr[p].rs, x, y, k);
tr[p].pushup(tr[tr[p].ls], tr[tr[p].rs]);
}
Node query(int p, int x, int y) {
int l = tr[p].l, r = tr[p].r;
// fprintf(stderr, "QUERY %d %d %d %d %d\n", p, l, r, x, y);
if (x <= l && r <= y)
return tr[p];
pushdown(p);
int mid = (l + r) >> 1;
Node res;
if (y <= mid)
res = query(tr[p].ls, x, y);
else if (mid < x)
res = query(tr[p].rs, x, y);
else
res.pushup(query(tr[p].ls, x, y), query(tr[p].rs, x, y));
return res;
}
int main() {
n = read(), m = read();
for (int i = 1; i <= n; i++)
val[i] = read();
rt = build(1, n);
// debug();
for (int i = 1; i <= m; i++) {
int k = read(), l = read() + 1, r = read() + 1;
if (1 <= k && k <= 3)
update(rt, l, r, k);
else {
Node p = query(rt, l, r);
if (k == 3)
printf("%d\n", p.v);
else
printf("%d\n", p.c1);
}
}
return 0;
}
自己条了半天了,发现 build
中似乎返回值有问题。