带标记的线段树
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e5 + 5;
struct Node {
int sum;
bool flip;
} seg[4 * MAXN];
string s;
int n, q;
void apply(int p, int l, int r) {
seg[p].sum = (r - l + 1) - seg[p].sum;
seg[p].flip ^= 1;
}
void push(int p, int l, int r) {
if (!seg[p].flip) return;
int mid = (l + r) >> 1;
apply(p << 1, l, mid);
apply(p << 1 | 1, mid + 1, r);
seg[p].flip = false;
}
void pull(int p) {
seg[p].sum = seg[p << 1].sum + seg[p << 1 | 1].sum;
}
void build(int p, int l, int r) {
if (l == r) {
seg[p].sum = s[l - 1] - '0';
return;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
pull(p);
}
void update(int p, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) {
apply(p, l, r);
return;
}
push(p, l, r);
int mid = (l + r) >> 1;
if (ql <= mid) update(p << 1, l, mid, ql, qr);
if (qr > mid) update(p << 1 | 1, mid + 1, r, ql, qr);
pull(p);
}
int query(int p, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) return seg[p].sum;
push(p, l, r);
int mid = (l + r) >> 1;
int res = 0;
if (ql <= mid) res += query(p << 1, l, mid, ql, qr);
if (qr > mid) res += query(p << 1 | 1, mid + 1, r, ql, qr);
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> q;
cin >> s;
build(1, 1, n);
while (q--) {
int op, l, r;
cin >> op >> l >> r;
if (op == 1) update(1, 1, n, l, r);
else cout << query(1, 1, n, l, r) << '\n';
}
return 0;
}

京公网安备 11010502036488号