The art of luogu P2574 XOR

analysis

First of all, it is not hard to see that this is a line tree problem. Then, because the operation to be maintained by this problem is different from that of the general line tree, it is considered to modify the pushdown function and lazy flag

Consider modifying the function. If you invert each number in the interval, the number of 1 = the number of interval elements - the number of original interval 1.

At this time, it's easy to think that the lazy flag represents the XOR of this interval, 1 represents XOR, 0 represents not XOR
Since A^ 1 ^1=A, if an interval is XOR twice, it is equivalent to not being XOR, that is to say, the lazy flag should also meet the XOR principle

Since then, the idea has been basically completed

code

#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)
int n,m;
const int maxn=200010;
int sum[maxn<<2],lazy[maxn<<2];
int a[maxn];
char _A[maxn];
template<typename T>void read(T &x){
    x=0;char r=getchar();T neg=1;
    while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
    while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
    x*=neg;
}
inline void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
inline void pushdown(int rt,int l,int r){
    if(!lazy[rt])return;
    int mid=(l+r)>>1;
    lazy[rt<<1]^=1;
    lazy[rt<<1|1]^=1;
    sum[rt<<1]=mid-l+1-sum[rt<<1];
    sum[rt<<1|1]=r-(mid+1)+1-sum[rt<<1|1];
    lazy[rt]=0;
}
void buildtree(int l,int r,int rt){
    if(l==r){
        sum[rt]=a[l];
        return;
    }
    int mid=((l+r)>>1);
    buildtree(l,mid,rt<<1);
    buildtree(mid+1,r,rt<<1|1);
    pushup(rt);
}
int query(int l,int r,int nl,int nr,int rt){
    if(l<=nl&&nr<=r)return sum[rt];
    pushdown(rt,nl,nr);
    int mid=((nl+nr)>>1);
    int _sum=0;
    if(mid>=l)_sum+=query(l,r,nl,mid,rt<<1);
    if(mid<r)_sum+=query(l,r,mid+1,nr,rt<<1|1);
    return _sum;
}
void update(int l,int r,int nl,int nr,int rt){
    if(l<=nl&&nr<=r){
        lazy[rt]^=1;
        sum[rt]=(nr-nl+1)-sum[rt];
        return;
    }
    pushdown(rt,nl,nr);
    int mid=((nl+nr)>>1);
    if(mid>=l)update(l,r,nl,mid,rt<<1);
    if(mid<r)update(l,r,mid+1,nr,rt<<1|1);
    pushup(rt);
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("datain.txt","r",stdin);
    #endif // ONLINE_JUDGE
    clean(sum,0),clean(lazy,0);
    read(n),read(m);
    scanf("%s",_A);
    loop(i,1,n)a[i]=_A[i-1]-'0';
    buildtree(1,n,1);
    loop(i,1,m){
        int _p,_l,_r;read(_p),read(_l),read(_r);
        if(_p==0)update(_l,_r,1,n,1);
        else if(_p==1)printf("%d\n",query(_l,_r,1,n,1));
    }
    return 0;
}

anayisis

That's the question above! No need to change the code

code

#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)
int n,m;
const int maxn=200010;
int sum[maxn<<2],lazy[maxn<<2];
int a[maxn];
char _A[maxn];
template<typename T>void read(T &x){
    x=0;char r=getchar();T neg=1;
    while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
    while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
    x*=neg;
}
inline void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
inline void pushdown(int rt,int l,int r){
    if(!lazy[rt])return;
    int mid=(l+r)>>1;
    lazy[rt<<1]^=1;
    lazy[rt<<1|1]^=1;
    sum[rt<<1]=mid-l+1-sum[rt<<1];
    sum[rt<<1|1]=r-(mid+1)+1-sum[rt<<1|1];
    lazy[rt]=0;
}
void buildtree(int l,int r,int rt){
    if(l==r){
        sum[rt]=a[l];
        return;
    }
    int mid=((l+r)>>1);
    buildtree(l,mid,rt<<1);
    buildtree(mid+1,r,rt<<1|1);
    pushup(rt);
}
int query(int l,int r,int nl,int nr,int rt){
    if(l<=nl&&nr<=r)return sum[rt];
    pushdown(rt,nl,nr);
    int mid=((nl+nr)>>1);
    int _sum=0;
    if(mid>=l)_sum+=query(l,r,nl,mid,rt<<1);
    if(mid<r)_sum+=query(l,r,mid+1,nr,rt<<1|1);
    return _sum;
}
void update(int l,int r,int nl,int nr,int rt){
    if(l<=nl&&nr<=r){
        lazy[rt]^=1;
        sum[rt]=(nr-nl+1)-sum[rt];
        return;
    }
    pushdown(rt,nl,nr);
    int mid=((nl+nr)>>1);
    if(mid>=l)update(l,r,nl,mid,rt<<1);
    if(mid<r)update(l,r,mid+1,nr,rt<<1|1);
    pushup(rt);
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("datain.txt","r",stdin);
    #endif // ONLINE_JUDGE
    clean(sum,0),clean(lazy,0);
    read(n),read(m);
    loop(i,1,m){
        int _p,_l,_r;read(_p),read(_l),read(_r);
        if(_p==0)update(_l,_r,1,n,1);
        else if(_p==1)printf("%d\n",query(_l,_r,1,n,1));
    }
    return 0;
}
*

Posted by markanite on Mon, 18 Nov 2019 08:53:31 -0800