heptari @ 2022-11-11 11:11:05
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define MAXN 100005
#define pushup(now) tree[now] = tree[now<<1] + tree[now<<1|1]
struct Tag {
int g1, g2;
Tag(int G1 = -1, int G2 = 0): g1(G1), g2(G2) {} //g1: 平推 g2:取反
Tag operator + (Tag y) {
if (g1 == -1 && g2 == 0) return y;
if (y.g1 == -1 && y.g2 == 0) return *this;
if (y.g1 != -1 && y.g2 == 0) return y;
if (y.g1 == -1) {
//g1 == 0 && g2 == 0 : 0
//g1 == 1 && g2 == 0 : 1
//g1 == 0 && g2 == 1 : 1
//g1 == 1 && g2 == 1 : 1
g2 ^= y.g2;
return *this;
}
}
};
struct node {
int l, r, len, sum0, sum1, fi0, fi1, la0, la1, len0, len1;
Tag tag;
node operator + (node x) {
node t;
t.l = l;
t.r = x.r;
t.len = len + x.len;
t.sum0 = sum0 + x.sum0;
t.sum1 = sum1 + x.sum1;
if (len == fi0) t.fi0 = fi0 + x.fi0;
else t.fi0 = fi0;
if (len == fi1) t.fi1 = fi1 + x.fi1;
else t.fi1 = fi1;
if (x.la0 == x.len) t.la0 = la0 + x.len;
else t.la0 = x.la0;
if (x.la1 == x.len) t.la1 = la1 + x.len;
else t.la1 = x.la1;
t.len0 = max(len0, max(x.len0, (la0 + x.fi0)));
t.len1 = max(len1, max(x.len1, (la1 + x.fi1)));
t.tag = Tag();
return t;
}
void operator += (Tag x) {
if (x.g1 == 0) {
fi0 = la0 = len0 = sum0 = len;
fi1 = la1 = len1 = sum1 = 0;
}
if (x.g1 == 1) {
fi0 = la0 = len0 = sum0 = 0;
fi1 = la1 = len1 = sum1 = len;
}
if (x.g2 == 1) {
swap(fi0, fi1);
swap(la0, la1);
swap(len0, len1);
swap(sum0, sum1);
}
tag = tag + x;
}
} tree[MAXN << 2];
void pushdown(int now) {
tree[now << 1] += tree[now].tag;
tree[now << 1 | 1] += tree[now].tag;
tree[now].tag = Tag();
}
int arr[MAXN];
void build(int l, int r, int now) {
if (l == r) {
tree[now].l = l;
tree[now].r = r;
tree[now].len = 1;
if (arr[l] == 1) {
tree[now].fi0 = tree[now].la0 = tree[now].len0 = tree[now].sum0 = 0;
tree[now].fi1 = tree[now].la1 = tree[now].len1 = tree[now].sum1 = 1;
} else {
tree[now].fi0 = tree[now].la0 = tree[now].len0 = tree[now].sum0 = 1;
tree[now].fi1 = tree[now].la1 = tree[now].len1 = tree[now].sum1 = 0;
}
tree[now].tag = Tag();
return;
}
int mid = (l + r) >> 1;
build(l, mid, now << 1);
build(mid + 1, r, now << 1 | 1);
pushup(now);
}
void modify(int l, int r, Tag tag, int now) {
if (tree[now].l != tree[now].r) pushdown(now);
if (l <= tree[now].l && tree[now].r <= r) {
tree[now] += tag;
return;
}
int mid = (tree[now].l + tree[now].r) >> 1;
if (l <= mid) modify(l, r, tag, now << 1);
if (r > mid) modify(l, r, tag, now << 1 | 1);
pushup(now);
}
node query(int l, int r, int now) {
if (tree[now].l != tree[now].r) pushdown(now);
if (l <= tree[now].l && tree[now].r <= r) return tree[now];
int mid = (tree[now].l + tree[now].r) >> 1;
if (l <= mid && r > mid) return query(l, r, now << 1) + query(l, r, now << 1 | 1);
if (l <= mid) return query(l, r, now << 1);
if (r > mid) return query(l, r, now << 1 | 1);
}
signed main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> arr[i];
build(1, n, 1);
while (m--) {
int opt, l, r;
cin >> opt >> l >> r;
if (opt == 0) modify(l + 1, r + 1, {0, 0}, 1);
if (opt == 1) modify(l + 1, r + 1, {1, 0}, 1);
if (opt == 2) modify(l + 1, r + 1, {-1, 1}, 1);
if (opt == 3) cout << query(l + 1, r + 1, 1).sum1 << endl;
if (opt == 4) cout << query(l + 1, r + 1, 1).len1 << endl;
}
return 0;
}
by w23c3c3 @ 2022-11-11 11:16:31
会不会 tag+tag 有可能没 return。
没仔细看代码。
by heptari @ 2022-11-11 11:18:31
@w23c3c3 return之后也是20(哭
by w23c3c3 @ 2022-11-11 11:27:40
但是应该就是 tag+tag 没 return 啊(
by w23c3c3 @ 2022-11-11 11:28:24
应该是 return y 你看看对不对。
by heptari @ 2022-11-11 11:29:32
@w23c3c3 对了~ 谢谢啦