• 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)<<"
    ";
            }else {
                scanf("%d %d %d",&l,&r,&val);
                update(1,n,1,l,r,val);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    推箱子
    为textarea增加maxlength属性(转)
    validate
    keypress
    Knockout
    &amp; replace &
    银联参数
    chinapay
    model binding
    JSON.stringify
  • 原文地址:https://www.cnblogs.com/MengX/p/10914788.html
Copyright © 2020-2023  润新知