XOR的艺术
用线段树维护sum,
修改时
tag[p]^=1;
sum=r-l+1-sum;
详见代码
#include<iostream> #include<cstdio> using namespace std; #define N 800010 #define lc(p) (p<<1) #define rc(p) (p<<1|1) #define mid ((l+r)>>1) int n,m,sum[N],dealta[N],cnt; char s[N>>2]; inline int read(){ int x=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); } return x; } void push_up(int p){ sum[p]=sum[lc(p)]+sum[rc(p)]; } void build(int p=1,int l=1,int r=n){ if(l==r){ sum[p]=s[++cnt]-'0'; return; } build(lc(p),l,mid); build(rc(p),mid+1,r); push_up(p); } void f(int p,int l,int r){ dealta[p]^=1; sum[p]=r-l+1-sum[p]; } void push_down(int p,int l,int r){ if(dealta[p]){ f(lc(p),l,mid); f(rc(p),mid+1,r); dealta[p]=0; } } void update(int L,int R,int p=1,int l=1,int r=n){ if(L<=l&&r<=R){ dealta[p]^=1; sum[p]=r-l+1-sum[p]; return; } push_down(p,l,r); if(L<=mid) update(L,R,lc(p),l,mid); if(R>mid) update(L,R,rc(p),mid+1,r); push_up(p); } int query(int L,int R,int p=1,int l=1,int r=n){ if(L<=l&&r<=R){ return sum[p]; } push_down(p,l,r); int ans=0; if(L<=mid) ans+=query(L,R,lc(p),l,mid); if(R>mid) ans+=query(L,R,rc(p),mid+1,r); push_up(p); return ans; } int main() { scanf("%d%d",&n,&m); scanf("%s",s+1); build(); int type,l,r; while(m--){ type=read(); l=read(); r=read(); if(type) printf("%d ",query(l,r)); else update(l,r); } return 0; }
三倍经验:
开关
光开关
去掉build即可