1. 程式人生 > >bzoj1230 開關燈 線段樹

bzoj1230 開關燈 線段樹

div scanf cout return c++ size lazy ont sum

好久沒寫線段樹了。。被一道線段樹裸題卡了一個上午

對區間進行異或,查詢的時候直接用區間長度減去原有是數量就是改變完的數量

#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; }

bzoj1230 開關燈 線段樹