【洛谷P2574】XOR的艺术

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\n",query(l,r));
        else update(l,r);
    }
    return 0;
}

 

三倍经验:

开关

光开关

去掉build即可

posted @ 2018-07-24 15:30  yjk  阅读(137)  评论(0编辑  收藏  举报