Codefoeces-242E XOR on Segment

https://codeforces.com/contest/242/problem/E

区间异或与区间求和

思路:我们只需要建20颗线段树,存每一位的值。每次更新成段更新对应位,查询时求出整个区间每一位上的值 还原成贡献就行。

#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const int maxn = 100000+5;
int lazy[maxn<<2],tree[25][maxn<<2],a[maxn];
void push_up(int rt){
    for(int i=0;i<20;i++)
        tree[i][rt]=tree[i][rt<<1]+tree[i][rt<<1|1];
}
void push_down(int l,int r,int rt){
    if(lazy[rt]){
        int m=(l+r)>>1;
        lazy[rt<<1]^=lazy[rt];
        lazy[rt<<1|1]^=lazy[rt];
        for(int i=0;i<20;i++){
            if(!(lazy[rt]&(1<<i))) continue;
            tree[i][rt<<1]=m-l+1-tree[i][rt<<1];
            tree[i][rt<<1|1]=r-m-tree[i][rt<<1|1];
        }
        lazy[rt]=0;
    }
    
}
void build(int l,int r,int rt){
    if(l==r){
        for(int i=0;i<20;i++){
            if(!(a[l]&(1<<i))) continue;
            tree[i][rt]=1;
        }
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    push_up(rt);
}
void update(int l,int r,int rt,int L,int R,int val){
    if(L<=l&&r<=R){
        lazy[rt]^=val;
        for(int i=0;i<20;i++){
            if(!(val&(1<<i))) continue;
            tree[i][rt]=r-l+1-tree[i][rt]; //整个区间异或 相同为0所以减去tree[i][rt]
        }
        return ;
    }
    push_down(l,r,rt);
    int m=(l+r)>>1;
    if(L<=m) update(lson,L,R,val);
    if(R>m) update(rson,L,R,val);
    push_up(rt);
}
ll query(int l,int r,int rt,int L,int R){
    if(L<=l&&r<=R){
        ll ans=0;
        for(int i=0;i<20;i++){
            ans+=(ll)tree[i][rt]<<i;
        }
        return ans;
    }
    int m=(l+r)>>1;
    push_down(l,r,rt);
    ll res=0;
    if(L<=m) res+=query(lson,L,R);
    if(R>m) res+=query(rson,L,R);
    return res;
}
int main(){
    int n,m;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    build(1,n,1);
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        int op,l,r,val;
        scanf("%d",&op);
        if(op==1){
            scanf("%d %d",&l,&r);
            cout<<query(1,n,1,l,r)<<"\n";
        }else {
            scanf("%d %d %d",&l,&r,&val);
            update(1,n,1,l,r,val);
        }
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/MengX/p/10914788.html
xor