【luogu2574】xor的艺术

一道无聊的线段树题,写着玩玩而已……

#include<bits/stdc++.h>
#define N 1000010
#define lson (o<<1)
#define rson (o<<1|1)
using namespace std;
int n,m,a[N];
struct Segment_Tree{
    int sumv[N<<2],xorv[N<<2],lenv[N];
    inline void pushup(int o){sumv[o]=sumv[lson]+sumv[rson];}
    inline void pushdown(int o){
        if(!xorv[o])return;
        xorv[o]=0;
        xorv[lson]=!xorv[lson];xorv[rson]=!xorv[rson];
        sumv[lson]=lenv[lson]-sumv[lson];
        sumv[rson]=lenv[rson]-sumv[rson];
    }
    void build(int o,int l,int r){
        lenv[o]=r-l+1;
        if(l==r){sumv[o]=a[l];return;}
        int mid=(l+r)>>1;
        build(lson,l,mid);build(rson,mid+1,r);
        pushup(o);
    }
    void change(int o,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
            xorv[o]=!xorv[o];sumv[o]=lenv[o]-sumv[o];
            return;
        }
        int mid=(l+r)>>1;pushdown(o);
        if(ql<=mid)change(lson,l,mid,ql,qr);
        if(qr>mid)change(rson,mid+1,r,ql,qr);
        pushup(o);
    }
    int querysum(int o,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr)return sumv[o];
        int mid=(l+r)>>1,ans=0;pushdown(o);
        if(ql<=mid)ans+=querysum(lson,l,mid,ql,qr);
        if(qr>mid)ans+=querysum(rson,mid+1,r,ql,qr);
        return ans;
    }
}T;
inline int read(){
    int f=1,x=0;char ch;
    do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
    do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
    return f*x;
}
int main(){
    n=read();m=read();
    for(int i=1;i<=n;++i)scanf("%1d",&a[i]);
    T.build(1,1,n);
    while(m--){
        int opt=read(),l=read(),r=read();
        if(opt==0)T.change(1,1,n,l,r);
        else printf("%d\n",T.querysum(1,1,n,l,r));
    }
    return 0;
}
 
posted @ 2017-05-14 20:57  zcysky  阅读(226)  评论(0编辑  收藏  举报