「洛谷3870」「TJOI2009」开关【线段树】

include <bits/stdc++.h>

using namespace std;
const int N = 100000 + 6;
int n, m;
namespace seg {
#define lc (nod << 1)
#define rc (nod << 1 | 1)
struct node {
int l, r, tg, s;
} tr[N << 2];
void pushup(int nod) { tr[nod].s = tr[lc].s + tr[rc].s; }
void pushdown(int nod, int l, int r) {
if (!tr[nod].tg) return;
int mid = (l + r) >> 1;
tr[lc].s = (mid - l + 1) - tr[lc].s; tr[lc].tg ^= 1;
tr[rc].s = (r - mid) - tr[rc].s; tr[rc].tg ^= 1;
tr[nod].tg = 0;
}
void build(int nod, int l, int r) {
tr[nod].l = l, tr[nod].r = r, tr[nod].s = 0, tr[nod].tg = 0;
if (l == r) return;
int mid = (l + r) >> 1;
build(lc, l, mid); build(rc, mid + 1, r);
pushup(nod);
}
void upd(int nod, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) {
tr[nod].s = (r - l + 1) - tr[nod].s;
tr[nod].tg ^= 1;
return;
}
int mid = (l + r) >> 1;
pushdown(nod, l, r);
if (ql <= mid) upd(lc, l, mid, ql, qr);
if (qr > mid) upd(rc, mid + 1, r, ql, qr);
pushup(nod);
}
int query(int nod, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) return tr[nod].s;
int mid = (l + r) >> 1, res = 0;
pushdown(nod, l, r);
if (ql <= mid) res += query(lc, l, mid, ql, qr);
if (qr > mid) res += query(rc, mid + 1, r, ql, qr);
return res;
}
}
int main() {
scanf("%d%d", &n, &m);
seg::build(1, 1, n);
for (int i = 1; i <= m; i ++) {
int opt, x, y; scanf("%d%d%d", &opt, &x, &y);
if (opt == 0) seg::upd(1, 1, n, x, y);
else printf("%d\n", seg::query(1, 1, n, x, y));
}
return 0;
}

猜你喜欢

转载自www.cnblogs.com/chhokmah/p/10779705.html