AC 的:
#include <iostream>
#define lc (o << 1)
#define rc (o << 1 | 1)
using namespace std;
const int S = 2e5 + 5;
int n, q;
int a[S], sum[S * 4];
int tag[S * 4];
void pushup(int o) {
sum[o] = sum[lc] + sum[rc];
return;
}
void pushdown(int o, int l, int r) {
if (tag[o] > 0) {
tag[lc] = (tag[lc] + tag[o]) % 2;
tag[rc] = (tag[rc] + tag[o]) % 2;
tag[o] = 0;
int mid = l + r >> 1;
sum[lc] = (mid - l + 1) - sum[lc];
sum[rc] = (r - mid) - sum[rc];
}
return;
}
void build(int o, int l, int r) {
if (l == r) {
sum[o] = a[l];
return;
}
int mid = l + r >> 1;
build(lc, l, mid);
build(rc, mid + 1, r);
pushup(o);
}
void update(int o, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) {
tag[o] ^= 1;
sum[o] = (r - l + 1) - sum[o];
return;
}
pushdown(o, l, r);
int mid = l + r >> 1;
if (ql <= mid) {
update(lc, l, mid, ql, qr);
}
if (mid < qr) {
update(rc, mid + 1, r, ql, qr);
}
pushup(o);
}
int query(int o, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) {
return sum[o];
}
int mid = l + r >> 1;
pushdown(o, l, r);
int ans = 0;
if (ql <= mid) {
ans += query(lc, l, mid, ql, qr);
}
if (mid < qr) {
ans += query(rc, mid + 1, r, ql, qr);
}
return ans;
}
int main() {
cin >> n >> q;
char c;
for (int i = 1; i <= n; i++) {
cin >> c;
a[i] = c - '0';
}
build (1, 1, n);
int op, l, r;
while (q--) {
cin >> op >> l >> r;
if (!op) {
update(1, 1, n, l, r);
} else {
cout << query(1, 1, n, l, r) << endl;
}
}
return 0;
}
WA 的:
#include <iostream>
#define lc (o << 1)
#define rc (o << 1 | 1)
using namespace std;
const int S = 2e5 + 5;
int n, q;
int a[S], sum[S * 4];
int tag[S * 4];
void pushup(int o) {
sum[o] = sum[lc] + sum[rc];
return;
}
void pushdown(int o, int l, int r) {
tag[lc] = (tag[lc] + tag[o]) % 2;
tag[rc] = (tag[rc] + tag[o]) % 2;
tag[o] = 0;
int mid = l + r >> 1;
if (tag[lc]) {
sum[lc] = (mid - l + 1) - sum[lc];
}
if (tag[rc]) {
sum[rc] = (r - mid) - sum[rc];
}
return;
}
void build(int o, int l, int r) {
if (l == r) {
sum[o] = a[l];
return;
}
int mid = l + r >> 1;
build(lc, l, mid);
build(rc, mid + 1, r);
pushup(o);
}
void update(int o, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) {
tag[o] ^= 1;
if (tag[o]) {
sum[o] = (r - l + 1) - sum[o];
}
return;
}
pushdown(o, l, r);
int mid = l + r >> 1;
if (ql <= mid) {
update(lc, l, mid, ql, qr);
}
if (mid < qr) {
update(rc, mid + 1, r, ql, qr);
}
pushup(o);
}
int query(int o, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) {
return sum[o];
}
int mid = l + r >> 1;
pushdown(o, l, r);
int ans = 0;
if (ql <= mid) {
ans += query(lc, l, mid, ql, qr);
}
if (mid < qr) {
ans += query(rc, mid + 1, r, ql, qr);
}
return ans;
}
int main() {
cin >> n >> q;
char c;
for (int i = 1; i <= n; i++) {
cin >> c;
a[i] = c - '0';
}
build (1, 1, n);
int op, l, r;
while (q--) {
cin >> op >> l >> r;
if (!op) {
update(1, 1, n, l, r);
} else {
cout << query(1, 1, n, l, r) << endl;
}
}
return 0;
}
两段代码的差异仅仅是在修改 sum 数组时判断 tag[o] 是否等于 0
我觉得 tag[o] 等于 0 的话不就是改了偶数次等于没改吗,为什么不对啊
求大佬指教 Orz