yu__xuan @ 2020-08-12 06:49:13
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define MAXN 100001
#define lson now << 1
#define rson now << 1 | 1
int max(int a, int b) { return a > b ? a : b; }
int n, m;
struct Node {
int l, r, w, lazy, tag;
int lmax1, rmax1, maxx1;
int lmax0, rmax0, maxx0;
}tree[MAXN << 2];
void pushup(int now) {
tree[now].w = tree[lson].w + tree[rson].w;
if (tree[lson].lmax1 == tree[lson].r - tree[lson].l + 1 && tree[rson].lmax1) tree[now].lmax1 = tree[lson].lmax1 + tree[rson].lmax1;
else tree[now].lmax1 = tree[lson].lmax1;
if (tree[rson].rmax1 == tree[rson].r - tree[rson].l + 1 && tree[lson].rmax1) tree[now].rmax1 = tree[lson].rmax1 + tree[rson].rmax1;
else tree[now].rmax1 = tree[rson].rmax1;
tree[now].maxx1 = max(tree[lson].maxx1, tree[rson].maxx1);
if (tree[lson].rmax1 && tree[rson].lmax1) tree[now].maxx1 = max(tree[now].maxx1, tree[lson].rmax1 + tree[rson].lmax1);
if (tree[lson].lmax0 == tree[lson].r - tree[lson].l + 1 && tree[rson].lmax0) tree[now].lmax0 = tree[lson].lmax0 + tree[rson].lmax0;
else tree[now].lmax0 = tree[lson].lmax0;
if (tree[rson].rmax0 == tree[rson].r - tree[rson].l + 1 && tree[lson].rmax0) tree[now].rmax0 = tree[lson].rmax0 + tree[rson].rmax0;
else tree[now].rmax0 = tree[rson].rmax0;
tree[now].maxx0 = max(tree[lson].maxx0, tree[rson].maxx0);
if (tree[lson].rmax0 && tree[rson].lmax0) tree[now].maxx0 = max(tree[now].maxx0, tree[lson].rmax0 + tree[rson].lmax0);
}
void build(int l, int r, int now) {
tree[now].lazy = -1, tree[now].l = l, tree[now].r = r;
if (tree[now].l == tree[now].r) {
scanf("%d", &tree[now].w);
tree[now].lmax1 = tree[now].maxx1 = tree[now].rmax1 = tree[now].w;
tree[now].lmax0 = tree[now].maxx0 = tree[now].rmax0 = tree[now].w ^ 1;
return;
}
int mid = (tree[now].l + tree[now].r) >> 1;
build(l, mid, lson), build(mid + 1, r, rson);
pushup(now);
}
void pushdown(int now) {
if (tree[now].l == tree[now].r) return;
tree[lson].lazy = tree[rson].lazy = tree[now].lazy;
tree[lson].w = (tree[lson].r - tree[lson].l + 1) * tree[now].lazy;
tree[lson].maxx1 = tree[lson].lmax1 = tree[lson].rmax1 = tree[lson].w;
tree[lson].maxx0 = tree[lson].lmax0 = tree[lson].rmax0 = (tree[lson].r - tree[lson].l + 1) - tree[lson].w;
tree[rson].w = (tree[rson].r - tree[rson].l + 1) * tree[now].lazy;
tree[rson].maxx1 = tree[rson].lmax1 = tree[rson].rmax1 = tree[rson].w;
tree[rson].maxx0 = tree[rson].lmax0 = tree[rson].rmax0 = (tree[rson].r - tree[rson].l + 1) - tree[rson].w;
tree[now].lazy = -1;
}
void pushdown1(int now) {
if (tree[now].l == tree[now].r) return;
tree[lson].tag = tree[rson].tag = 1;
tree[lson].w = (tree[lson].r - tree[lson].l + 1) - tree[lson].w;
int temp = tree[lson].maxx1; tree[lson].maxx1 = tree[lson].maxx0, tree[lson].maxx0 = temp;
temp = tree[lson].lmax1, tree[lson].lmax1 = tree[lson].lmax0, tree[lson].lmax0 = temp;
temp = tree[lson].rmax1, tree[lson].rmax1 = tree[lson].rmax0, tree[lson].rmax0 = temp;
tree[rson].w = (tree[rson].r - tree[rson].l + 1) - tree[rson].w;
temp = tree[rson].maxx1, tree[rson].maxx1 = tree[rson].maxx0, tree[rson].maxx0 = temp;
temp = tree[rson].lmax1, tree[rson].lmax1 = tree[rson].lmax0, tree[rson].lmax0 = temp;
temp = tree[rson].rmax1, tree[rson].rmax1 = tree[rson].rmax0, tree[rson].rmax0 = temp;
tree[now].tag = 0;
}
void update1(int x, int y, int k, int now) {
if (tree[now].l >= x && tree[now].r <= y) {
tree[now].w = (tree[now].r - tree[now].l + 1) * k;
tree[now].maxx1 = tree[now].lmax1 = tree[now].rmax1 = tree[now].w;
tree[now].maxx0 = tree[now].lmax0 = tree[now].rmax0 = (tree[now].r - tree[now].l + 1) - tree[now].w;
tree[now].tag = 0, tree[now].lazy = k; return;
}
if (tree[now].tag) pushdown1(now);
if (tree[now].lazy != -1) pushdown(now);
int mid = (tree[now].l + tree[now].r) >> 1;
if (x <= mid) update1(x, y, k, lson);
if (y > mid) update1(x, y, k, rson);
pushup(now);
}
void update2(int x, int y, int now) {
if (tree[now].l >= x && tree[now].r <= y) {
tree[now].w = (tree[now].r - tree[now].l + 1) - tree[now].w;
int temp = tree[now].maxx1; tree[now].maxx1 = tree[now].maxx0, tree[now].maxx0 = temp;
temp = tree[now].lmax1, tree[now].lmax1 = tree[now].lmax0, tree[now].lmax0 = temp;
temp = tree[now].rmax1, tree[now].rmax1 = tree[now].rmax0, tree[now].rmax0 = temp;
if (tree[now].lazy != -1) tree[now].lazy ^= 1;
else tree[now].tag = 1;
return;
}
if (tree[now].tag) pushdown1(now);
if (tree[now].lazy != -1) pushdown(now);
int mid = (tree[now].l + tree[now].r) >> 1;
if (x <= mid) update2(x, y, lson);
if (y > mid) update2(x, y, rson);
pushup(now);
}
int query1(int x, int y, int now) {
if (tree[now].l >= x && tree[now].r <= y) return tree[now].w;
if (tree[now].tag) pushdown1(now);
if (tree[now].lazy != -1) pushdown(now);
int mid = (tree[now].l + tree[now].r) >> 1, ans = 0;
if (x <= mid) ans += query1(x, y, lson);
if (y > mid) ans += query1(x, y, rson);
return ans;
}
Node merge(Node left, Node right) {
Node ans;
ans.w = left.w + right.w;
if (left.lmax1 == left.r - left.l + 1 && right.lmax1) ans.lmax1 = left.lmax1 + right.lmax1;
else ans.lmax1 = left.lmax1;
if (right.rmax1 == right.r - right.l + 1 && left.rmax1) ans.rmax1 = left.rmax1 + right.rmax1;
else ans.rmax1 = right.rmax1;
ans.maxx1 = max(left.maxx1, right.maxx1);
if (left.rmax1 && right.lmax1) ans.maxx1 = max(ans.maxx1, left.rmax1 + right.lmax1);
if (left.lmax0 == left.r - left.l + 1 && right.lmax0) ans.lmax0 = left.lmax0 + right.lmax0;
else ans.lmax0 = left.lmax0;
if (right.rmax0 == right.r - right.l + 1 && left.rmax0) ans.rmax0 = left.rmax0 + right.rmax0;
else ans.rmax0 = right.rmax0;
ans.maxx0 = max(left.maxx0, right.maxx0);
if (left.rmax0 && right.lmax0) ans.maxx0 = max(ans.maxx0, left.rmax0 + right.lmax0);
return ans;
}
Node query2(int x, int y, int now) {
if (tree[now].l >= x && tree[now].r <= y) return tree[now];
if (tree[now].tag) pushdown1(now);
if (tree[now].lazy != -1) pushdown(now);
int mid = (tree[now].l + tree[now].r) >> 1;
if (x > mid) return query2(x, y, rson);
else if (y <= mid) return query2(x, y, lson);
else return merge(query2(x, y, lson), query2(x, y, rson));
}
int main() {
scanf("%d %d", &n, &m);
build(1, n, 1);
for (int i = 1, opt, x, y; i <= m; ++i) {
scanf("%d %d %d", &opt, &x, &y);
++x, ++y;
if (opt == 0) update1(x, y, 0, 1);
if (opt == 1) update1(x, y, 1, 1);
if (opt == 2) update2(x, y, 1);
if (opt == 3) printf("%d\n", query1(x, y, 1));
if (opt == 4) printf("%d\n", query2(x, y, 1).maxx1);
}
return 0;
}
by xwmwr @ 2020-08-12 09:43:25
@yu__xuan 还在调吗, 我有点闲想练下调试
by yu__xuan @ 2020-08-12 09:48:35
@水比田昭寿 在调
by yu__xuan @ 2020-08-12 10:06:45
@水比田昭寿 下放区间取反,和区间取反的懒标那里有错误,改了之后过了一个点qwq
by xwmwr @ 2020-08-12 10:11:20
@yu__xuan 这个写法似乎很香
by yu__xuan @ 2020-08-12 10:11:23
@水比田昭寿 过了,就是区间取反的懒标处理有问题qwq
by xwmwr @ 2020-08-12 10:13:13
@yu__xuan 那我根勃去了
by yu__xuan @ 2020-08-12 10:14:12
@水比田昭寿 好,那我去点赞/cy
by guodong @ 2020-09-10 12:28:05
10 3
1 1 1 1 0 1 0 1 0 1
2 1 7
4 7 9
3 1 5
补一下(