拜线段树的最好办法是研究线段树,研究线段树的好方法是打线段树,然后我就去逝了,然后我wa了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+7;
typedef long long LL;
LL N,M,a[maxn];
struct node{LL l,r,dat,tag;}tree[maxn];
LL ls(LL p){return p<<1;}
LL rs(LL p){return p<<1|1;}
LL Len(LL p){return tree[p].r-tree[p].l+1;}
void update(LL p){tree[p].dat=Len(p)-tree[p].dat;return;}
void build(LL p,LL l,LL r){
tree[p].l=l;tree[p].r=r;tree[p].dat=0;
if(l==r){return;}
LL mid=(l+r)>>1;
build(ls(p),l,mid);build(rs(p),mid+1,r);
return;
}
void pushdown(LL p){
if(tree[p].tag==0)return;
LL L=ls(p),R=rs(p);
update(L);update(R);
tree[L].tag^=1;tree[R].tag^=1;
tree[p].tag=0;
return;
}
void change(LL p,LL l,LL r){
if(l<=tree[p].l&&tree[p].r<=r){update(p);tree[p].tag^=1;return;}
pushdown(p);
LL mid=(tree[p].l+tree[p].r)>>1;
if(l<=mid)change(ls(p),l,mid);
if(r>mid)change(rs(p),mid+1,r);
tree[p].dat=tree[ls(p)].dat+tree[rs(p)].dat;
return;
}
LL query(LL p,LL l,LL r){
if(l<=tree[p].l&&tree[p].r<=r)return tree[p].dat;
pushdown(p);
LL mid=(tree[p].l+tree[p].r)>>1,ret=0;
if(l<=mid)ret+=query(ls(p),l,mid);
if(r>mid)ret+=query(rs(p),mid+1,r);
return ret;
}
int main(){
cin>>N>>M;
build(1,1,N);
while(M--){
int op,a,b;
cin>>op>>a>>b;
if(!op)change(1,a,b);
else cout<<query(1,a,b)<<endl;
}
return 0;
}