bzoj1230 开关灯 线段树
好久没写线段树了。。被一道线段树裸题卡了一个上午
对区间进行异或,查询的时候直接用区间长度减去原有是数量就是改变完的数量
#include<bits/stdc++.h> using namespace std; #define maxn 100005 struct tree{ int l,r,sum; }t[maxn*4]; int n,m,ans; int lazy[maxn*4],a[maxn]; void add(int x,int l,int r){ lazy[x]^=1; t[x].sum=(r-l+1)-t[x].sum; } void build(int x,int l,int r){ t[x].l=l; t[x].r=r; if(l==r){ return; } int mid=(l+r)>>1; build(x*2,l,mid); build(x*2+1,mid+1,r); } void push(int x){ if(lazy[x]){ int mid=(t[x].l+t[x].r)>>1; add(x*2,t[x].l,mid);add(x*2+1,mid+1,t[x].r); lazy[x]=0; } } int query(int x,int l,int r){ if(l<=t[x].l&&r>=t[x].r){ return t[x].sum; } if(l>t[x].r||r<t[x].l) return 0; push(x); return query(x*2,l,r)+query(x*2+1,l,r); } void change(int x,int l,int r){ if(l<=t[x].l&&r>=t[x].r){ add(x,t[x].l,t[x].r); return ; } if(l>t[x].r||r<t[x].l) return ; push(x); int mid=(t[x].l+t[x].r)>>1; change(x*2,l,r); change(x*2+1,l,r); t[x].sum=t[x*2].sum+t[x*2+1].sum; } int main(){ scanf("%d%d",&n,&m); int x,y,z; build(1,1,n); for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); if(x==1){ ans=query(1,y,z); printf("%d\n",ans); } else { change(1,y,z); /*printf("\n{"); for(int i=1;i<=7;i++){ cout<<t[i].sum<<" "; } printf("}\n");*/ } } return 0; }