luogu P2574 XOR的艺术 P3870 [TJOI2009]开关

版权声明:thanks for your copy! https://blog.csdn.net/weixin_43907802/article/details/89785337

在这里插入图片描述

analysis

首先不难看出来这是一道线段树的题,然后由于这道题要维护的操作和一般的线段树不同,所以考虑修改pushdown函数和lazy标记

考虑修改函数,若将区间中每个数取反,那么其中的1的个数=区间元素个数-原区间1的个数。

此时容易想到让lazy标记代表此区间被XOR情况,1代表被XOR,0代表没有被XOR
由于A^ 1 ^1=A,一段区间如果被XOR两次,就相当于没有被XOR,即lazy标记也要满足XOR原则

自此思路基本完成

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

就是上面那道题嘛!代码都不用咋改(luogu上有3道和这个一模一样的题

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

猜你喜欢

转载自blog.csdn.net/weixin_43907802/article/details/89785337