代码如下(本人蒟蒻)
#include <bits/stdc++.h>
using namespace std;
const int maxn=100005;
struct tree{
int l,r;
int l0,l1,add; // l0:关着的灯的数量 l1:表示 亮着的灯的数量
} t[maxn*4];
void build(int u,int l,int r) //建树
{
t[u].l=l;
t[u].r=r;
if (l==r)
{
t[u].l0++;
return ;
}
int mid=(l+r)/2;
build(u*2,l,mid);
build(u<<1|1,mid+1,r);
t[u].l0=t[u*2].l0 + t[u<<1|1].l0;
}
inline void spread(int u) //打标记
{
if (t[u].add == 0) return ;
swap(t[u*2].l0,t[u*2].l1); //交换
swap(t[u<<1|1].l0, t[u<<1|1].l1);
t[u*2].add^=1; //开关灯就相当于^一下
t[u<<1|1].add^=1;
t[u].add=0;
}
int ask(int u,int l,int r) //查询开着的灯的数量
{
if (t[u].l>=l&&t[u].r<=r)
return t[u].l1;
spread(u);
int mid=(t[u].l+t[u].r)/2,sum = 0;
if(l<=mid) sum+=ask(u*2,l,r);
if(mid<r) sum+=ask(u<<1|1,l,r);
return sum;
}
void change(int u,int l,int r)//开关灯
{
if (t[u].l>=l&&t[u].r<=r)
{
t[u].add=1;
swap(t[u].l0,t[u].l1);
return ;
}
spread(u);
int mid = (t[u].l + t[u].r) / 2;
if (l <= mid) change(u*2, l, r);
if (mid < r) change(u<<1|1, l, r);
t[u].l0 = t[u*2].l0 + t[u<<1|1].l0;
t[u].l1 = t[u*2].l1 + t[u<<1|1].l1;
}
int main()
{
int n,m,opt,x,y;
cin>>n>>m;
build(1, 1, n);
for (int i=1;i<=m;i++)
{
cin>>opt>>x>>y;
if (opt == 0)
change(1, x, y);
else
cout<<ask(1, x, y)<<endl;
}
return 0;
}