线段树入门】P3870 开关(区间异或和)

发布时间 2023-12-12 11:15:24作者: iscr
 1 //笔记-自用
 2 //#pragma GCC optimize("Ofast")
 3 //#pragma GCC optimize("unroll-loops")
 4 #define _CRT_SECURE_NO_WARNINGS
 5 #define All(a) a.begin(),a.end()
 6 #define INF 2147483647
 7 #include<bits/stdc++.h>
 8 #include<numeric>
 9 using namespace std;
10 typedef unsigned long long ull;
11 #define int long long//再也不用担心开longlong了><
12 typedef pair<int, int>PII;
13 const int N = 1e5 + 5;
14 #define lc p<<1
15 #define rc p<<1|1
16 struct node {
17     int l, r, val, f;
18 }tr[N*4];
19 int w[N];
20 void pushup(int p) {
21     tr[p].val = tr[lc].val + tr[rc].val;
22 }
23 void pushdown(int p) {//值的更新其实就是区间长度-原长(另类区分??)
24     if (tr[p].f) {
25         tr[lc].val = (tr[lc].r - tr[lc].l + 1) - tr[lc].val;
26         tr[rc].val = (tr[rc].r - tr[rc].l + 1) - tr[rc].val;
27         tr[lc].f ^= 1;
28         tr[rc].f ^= 1;
29         tr[p].f = 0;
30     }
31 }
32 void build(int p, int l, int r) {//类比
33     tr[p] = { l,r,w[l],0 };
34     if (l == r)return;
35     int mid = l + r >> 1;
36     build(lc, l, mid);
37     build(rc, mid + 1, r);
38     pushup(p);
39 }
40 void update(int p, int x, int y) {//类比
41     if (x <= tr[p].l && tr[p].r <= y) {
42         tr[p].val = (tr[p].r - tr[p].l + 1) - tr[p].val;
43         tr[p].f ^= 1;
44         return;
45     }
46     int mid = tr[p].l + tr[p].r >> 1;
47     pushdown(p);
48     if (x <= mid)update(lc, x, y);
49     if (y > mid)update(rc, x, y);
50     pushup(p);
51 }
52 int query(int p, int x, int y) {//类比
53     if (x <= tr[p].l && tr[p].r <= y) {
54         return tr[p].val;
55     }
56     int mid = tr[p].l + tr[p].r >> 1;
57     pushdown(p);
58     int res = 0;
59     if (x <= mid)res += query(lc, x, y);
60     if (y > mid)res += query(rc, x, y);
61     return res;
62 }
63 signed main() {
64     ios::sync_with_stdio(false);
65     cin.tie(nullptr);
66     cout.tie(nullptr);
67     int n, m;
68     cin >> n >> m;
69     build(1, 1, n);
70     while (m--) {
71         int op, x, y;
72         cin >> op >> x >> y;
73         if (op == 0) {
74             update(1, x, y);
75         }
76         else {
77             cout << query(1, x, y) << "\n";
78         }
79     }
80 
81 }