代码如下
#include<bits/stdc++.h>
using namespace std;
const int maxn =2*10e5+10;
long long a[maxn]{0},w[maxn*4];
long long lzy[maxn*4];
void pushup(const int u)//维护
{
w[u] = w[u*2] + w[u*2+1]; //w[u] 是区间 u*2是左子树 u*2+1右子树
}
bool inRange(int L,int R,int l,int r)
{
return(l<=L)&&(R<=r);
}
bool outofRange(int L,int R,int l,int r)
{
return (L > r)||(R < l);
}
void maketag(int u, int len)
{
w[u]=len-w[u];
lzy[u]^=1;
}
void pushdown(int u,int l,int r)
{
int m = (l+r)/2;
maketag(u*2, m-l+1);//左子树加lzy[u]
maketag(u*2+1, r-m);//右子树加lzy[u]
lzy[u]=0;
}
long long query(int u,int L,int R,int l,int r)//区间查询
{
if(inRange(L,R,l,r))//如果完全包含返回区间值
{
return w[u];
}
else if(!outofRange(L,R,l,r))//若相交,递归处理
{
int m = (L + R)/2;
pushdown(u,L,R);//查询的时候也需要将节点标记下放
return query(u*2, L, m, l, r)+query(u*2+1, m+1, R, l, r);
}
else return 0;
}
void update(int u,int L,int R,int l,int r)
{
if(inRange(L,R,l,r))
{
maketag(u,R-L+1);//完全包含打包标记
}
else if(!outofRange(L,R,l,r))
{
int M =(L+R)/2;
pushdown(u,L,R);//先将当前节点标记下穿 然后修改下面的节点
update(u*2,L,M,l,r);
update(u*2+1,M+1,R,l,r);
pushup(u);
}
}
int main()
{
::ios_base::sync_with_stdio(false);
int n,m;
cin >> n >> m;
for(int t=1;t<=m;t++)
{
int op,x,y;
long long k;
cin >> op;
if(op==0)
{
cin >> x >> y ;
update(1,1,n,x,y);
}
else
{
cin >> x >> y;
cout << query(1,1,n,x,y) << '\n';
}
}
return 0;
}
我想的是把lazy ^1然后更新w中1的个数T T 不知道哪一步错了