线段树
题意:
给定一个01串
要求支持两种操作:
1 - 区间 xor
2 - 区间求和
做法:
普通的线段树的求和
用 rev 表示该区间是否被 xor
因为 xor 两次就相当于没有 xor
所以当区间 xor 的时候
对 rev 取反, sum = 区间长度 - sum
code:
#include <bits/stdc++.h>
using namespace std;
const int N = 2 * 100005;
int a[N], n, m, opt, L, R;
struct Stree {
int l, r, sum; bool rev;
}tree[N * 3];
template <typename T>
inline void read(T &t) {
t = 0; T m = 1; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') m = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') { t = (t << 3) + (t << 1) + (ch & 15); ch = getchar(); }
t *= m;
}
void pushup(int rt) {
tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
}
void pushdown(int rt) {
if(tree[rt].rev) {
tree[rt << 1].rev = !tree[rt << 1].rev, tree[rt << 1 | 1].rev = !tree[rt << 1 | 1].rev;
tree[rt << 1].sum = (tree[rt << 1].r - tree[rt << 1].l + 1 - tree[rt << 1].sum);
tree[rt << 1 | 1].sum = (tree[rt << 1 | 1].r - tree[rt << 1 | 1].l + 1 - tree[rt << 1 | 1].sum);
tree[rt].rev = 0;
}
}
void build(int l, int r, int rt) {
tree[rt].l = l, tree[rt].r = r, tree[rt].sum = 0, tree[rt].rev = 0;
if(l == r) {
tree[rt].sum = a[l]; return;
}
int mid = (l + r) >> 1;
build(l, mid, rt << 1), build(mid + 1, r, rt << 1 | 1);
pushup(rt);
}
int Quary(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) return tree[rt].sum;
pushdown(rt);
int mid = (l + r) >> 1, ans = 0;
if(L <= mid) ans += Quary(L, R, l, mid, rt << 1);
if(R > mid) ans += Quary(L, R, mid + 1, r, rt << 1 | 1);
return ans;
}
void upd(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
tree[rt].rev = !tree[rt].rev;
tree[rt].sum = (r - l + 1 - tree[rt].sum);
return;
}
pushdown(rt);
int mid = (l + r) >> 1;
if(L <= mid) upd(L, R, l, mid, rt << 1);
if(R > mid) upd(L, R, mid + 1, r, rt << 1 | 1);
pushup(rt);
}
int main() {
read(n), read(m);
for(int i = 1; i <= n; i++) {
scanf("%1d", &a[i]);
}
/*r(int i = 1; i <= n; i++) {
printf("%d%c", a[i], i == n ? '
' : ' ');
}*/
build(1, n, 1);
for(int i = 1; i <= m; i++) {
read(opt), read(L), read(R);
if(opt == 0) {
upd(L, R, 1, n, 1);
} else {
printf("%d
", Quary(L, R, 1, n, 1));
}
}
return 0;
}