rt
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#define maxn 1000010
using namespace std;
typedef long long ll; //开ll
/*
默写结构体线段树
范围为模板1-2
*/
int mod; //如果有模数的话
int z = 1;
struct node {
int l;
int r;
ll val;
ll add = 0; //加法标记 //开long long !!!! 十年OI一场空,不开longlong 见祖宗
ll add2 = 1;//乘法标记,默认为1
} a[maxn];
int num[maxn]; //存放值的数组
void build(int p, int l, int r) {
a[p].l = l;
a[p].r = r;
if (l == r) {
a[p].val = num[l];
return;
}
int mid = (l + r) / 2;
build(p * 2, l, mid); //建立左子树
build(p * 2 + 1, mid + 1, r); //建立右子树
a[p].val = a[p * 2].val + a[p * 2 + 1].val;
return;
}
/*
spread函数的标注:
1.区间+1的原因:假设 1 2 3 4 5,我的l为1,r为5,那么我用r - l为4,会忽略掉一个端点
(其实根节点设为0有可能不会出错但是根节点设为零p*2会出错)
*/
void spread(int p) { //下传操作
if (a[p].add) { //先乘后加,必须要打括号!!
/*a[p * 2].val += (a[p * 2].r - a[p * 2].l + 1) * a[p].add;
a[p * 2 + 1].val += (a[p * 2 + 1].r - a[p * 2 + 1].l + 1) * a[p].add; //注意:r为右端点,减的时候写前面
a[p * 2].add += a[p].add, a[p * 2 + 1].add += a[p].add; //对加法标记进行处理
a[p].add = 0;*/
a[p * 2].val = (a[p * 2].r - a[p * 2].l + 1 - a[p * 2].val); //实现异或操作
a[p * 2 + 1].val = (a[p * 2 + 1].r - a[p * 2 + 1].l + 1 - a[p * 2 + 1].val);
a[p * 2].add += a[p].add;
a[p * 2 + 1].add += a[p].add;
a[p].add = 0;
}
}
void change1(int p, int l, int r, int z) {
if (l <= a[p].l && r >= a[p].r) { //覆盖了
a[p].add ^= z;
a[p].val = r - l + 1 - a[p].val;
return;
}
spread(p);
int mid = (a[p].l + a[p].r) / 2; //注意:不是 l 与 r !!!
if (l <= mid) {
change1(p * 2, l, r, z);
}
if (r > mid) {
change1(p * 2 + 1, l, r, z);
}
a[p].val = a[p * 2].val + a[p * 2 + 1].val; //加上值
}
ll ask(int p, int l, int r) {
if (l <= a[p].l && r >= a[p].r) {
return a[p].val;
}
spread(p);
ll ans = 0;
int mid = (a[p].l + a[p].r) / 2;
if (l <= mid) {
ans += ask(p * 2, l, r);
}
if (r > mid) {
ans += ask(p * 2 + 1, l, r);
}
return ans;
}
int main() {
int n, m;
cin >> n >> m;
memset(num, 0, sizeof(num));
build(1, 1, n);
int op, l, r;
for (int i = 1; i <= m; i++) {
cin >> op >> l >> r;
if (op == 0) {
change1(1, l, r, 1);
} else {
cout << ask(1, l, r) << endl;
}
}
return 0;
}