# 「 Luogu P2574 」 XOR的艺术——线段树

## # 解题思路

• 异或了奇数次，$0$ 就会变成 $1$，$1$ 就会变成 $0$。
• 异或了偶数次，$0$ 和 $1$ 都不变。

## # 附上代码

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, m;
const int maxn = 2e5+3;
struct node {int l, r, sum, t, tag, flag;}tree[maxn << 2];
struct Tree {
#define Lson (k << 1)
#define Rson ((k << 1) | 1)
template <typename T> inline void read(T &x) {
x = 0; T f = 1; char c = getchar();
while (c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while (c <= '9' && c >= '0') {x = x*10 + c-'0'; c = getchar();}
x *= f;
}
void build(int k, int ll, int rr) {
tree[k].l = ll, tree[k].r = rr;
tree[k].flag = tree[k].t = 0;
if(tree[k].l == tree[k].r) {
scanf("%1d", &tree[k].sum);
return ;
}
int mid = (tree[k].l + tree[k].r) >> 1;
build(Lson, tree[k].l, mid);
build(Rson, mid+1, tree[k].r);
tree[k].sum = tree[Lson].sum + tree[Rson].sum;
}
void push_down(int k) {
tree[Lson].t += tree[k].tag;
tree[Rson].t += tree[k].tag;
tree[Lson].tag += tree[k].tag;
tree[Rson].tag += tree[k].tag;
tree[k].tag = 0;
}
void update(int k, int L, int R) {
if(tree[k].l >= L && tree[k].r <= R) {
tree[k].t ++;
tree[k].tag ++;
return;
}
tree[k].flag = 1;
if(tree[k].tag) push_down(k);
int mid = (tree[k].l + tree[k].r) >> 1;
if(L <= mid) update(Lson, L, R);
if(R > mid) update(Rson, L, R);
}
int query(int k, int L, int R) {
int ans = 0;
if(tree[k].l >= L && tree[k].r <= R && tree[k].flag == 0) {
if(tree[k].t % 2 == 1) return (tree[k].r-tree[k].l+1)-tree[k].sum;
else return tree[k].sum;
}
if(tree[k].tag) push_down(k);
int mid = (tree[k].l + tree[k].r) >> 1;
if(L <= mid) ans += query(Lson, L, R);
if(R > mid) ans += query(Rson, L, R);
return ans;
}
Tree () {
build(1, 1, n);
int opt, l, r;
for(int i=1; i<=m; i++) {
if(opt == 0) update(1, l, r);
else printf("%d\n", query(1, l, r));
}
}
}T;
int main() {return 0;}

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, m;
const int maxn = 2e5+3;
struct node {int l, r, sum, t, tag, flag;}tree[maxn << 2];
struct Tree {
#define Lson (k << 1)
#define Rson ((k << 1) | 1)
template <typename T> inline void read(T &x) {
x = 0; T f = 1; char c = getchar();
while (c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while (c <= '9' && c >= '0') {x = x*10 + c-'0'; c = getchar();}
x *= f;
}
void build(int k, int ll, int rr) {
tree[k].l = ll, tree[k].r = rr;
tree[k].flag = tree[k].t = 0;
if(tree[k].l == tree[k].r) {
scanf("%1d", &tree[k].sum);
return ;
}
int mid = (tree[k].l + tree[k].r) >> 1;
build(Lson, tree[k].l, mid);
build(Rson, mid+1, tree[k].r);
tree[k].sum = tree[Lson].sum + tree[Rson].sum;
}
void push_down(int k) {
if(tree[k].tag % 2 == 1)
tree[Lson].sum = (tree[Lson].r-tree[Lson].l+1)-tree[Lson].sum,
tree[Rson].sum = (tree[Rson].r-tree[Rson].l+1)-tree[Rson].sum;
tree[Lson].tag += tree[k].tag;
tree[Rson].tag += tree[k].tag;
tree[k].tag = 0;
}
void update(int k, int L, int R) {
if(tree[k].l >= L && tree[k].r <= R) {
tree[k].tag ++;
tree[k].sum = (tree[k].r-tree[k].l+1)-tree[k].sum;
return;
}
if(tree[k].tag) push_down(k);
int mid = (tree[k].l + tree[k].r) >> 1;
if(L <= mid) update(Lson, L, R);
if(R > mid) update(Rson, L, R);
tree[k].sum = tree[Lson].sum + tree[Rson].sum;
}
int query(int k, int L, int R) {
int ans = 0;
if(tree[k].l >= L && tree[k].r <= R)
return tree[k].sum;
if(tree[k].tag) push_down(k);
int mid = (tree[k].l + tree[k].r) >> 1;
if(L <= mid) ans += query(Lson, L, R);
if(R > mid) ans += query(Rson, L, R);
return ans;
}
Tree () {
build(1, 1, n);
int opt, l, r;
for(int i=1; i<=m; i++) {
int main() {return 0;}