C 红球进黑洞

https://ac.nowcoder.com/acm/contest/6046/C

二维线段树+区间异或+区间求和

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstring>
  4 #include <cstdio>
  5 using namespace std;
  6 const int _max = 1e5+50;
  7 typedef long long ll;
  8 ll tree[_max<<2][25],lazy[_max<<2],a[_max];
  9 void pushup(int node)
 10 {
 11     for(int i=0;i<25;i++)
 12       tree[node][i]=tree[node<<1][i]+tree[node<<1|1][i];
 13 }
 14 void build(int node,int l,int r)
 15 {
 16     lazy[node]=0;
 17     if(l==r)
 18     {
 19         for(int i=0;i<24;i++)
 20           ((ll)(1<<i)&a[l])?tree[node][i]=1:tree[node][i]=0;
 21         return;
 22     }
 23     int mid=(l+r)>>1;
 24     build(node<<1,l,mid);
 25     build(node<<1|1,mid+1,r);
 26     pushup(node);
 27 }
 28 void pushdown(int node,int l,int r)
 29 {
 30     int mid=(l+r)>>1;
 31     if(lazy[node])
 32     {
 33         lazy[node<<1|1]^=lazy[node];
 34         lazy[node<<1]^=lazy[node];
 35         for(int i=0;i<25;i++)
 36         {
 37             int t=(lazy[node]>>i)&1;
 38             if(t)
 39             {
 40                 tree[node<<1][i]=mid-l+1-tree[node<<1][i];
 41                 tree[node<<1|1][i]=r-mid-tree[node<<1|1][i];
 42             }
 43         }
 44         lazy[node]=0;
 45     }
 46 }
 47 void update(int node,int l,int r,int st,int en,int val)
 48 {
 49     int mid=(l+r)>>1;
 50     if(st<=l&&r<=en)
 51     {
 52         lazy[node]^=val;
 53         for(int i=0;i<25;i++)
 54         {
 55             int t=(val>>i)&1;
 56             if(t)
 57               tree[node][i]=r-l+1-tree[node][i];
 58         }
 59         return ;
 60     }
 61     pushdown(node,l,r);
 62     if(st<=mid)
 63       update(node<<1,l,mid,st,en,val);
 64     if(en>mid)
 65       update(node<<1|1,mid+1,r,st,en,val);
 66     pushup(node);
 67 }
 68 ll query(int node,int l,int r,int st,int en)
 69 {
 70     if(st<=l&&en>=r)
 71     {
 72         ll ans=0;
 73         for(int i=0;i<25;i++)
 74           ans+=(ll)(1<<i)*tree[node][i];
 75         return ans;
 76     }
 77     pushdown(node,l,r);
 78     int mid=(l+r)>>1;
 79     ll ans1=0,ans2=0;
 80     if(st<=mid)
 81       ans1=query(node<<1,l,mid,st,en);
 82     if(en>mid)
 83       ans2=query(node<<1|1,mid+1,r,st,en);
 84     return ans1+ans2;
 85 }
 86 int main()
 87 {
 88     int n,m;
 89     scanf("%d%d",&n,&m);
 90     for(int i=1;i<=n;i++)
 91       scanf("%d",&a[i]);
 92     build(1,1,n);
 93     while(m--)
 94     {
 95         int f,l,r,k;
 96         scanf("%d",&f);
 97         if(f==1)
 98         {
 99             scanf("%d%d",&l,&r);
100             cout<<query(1,1,n,l,r)<<endl;
101         }
102         else
103         {
104             scanf("%d%d%d",&l,&r,&k);
105             update(1,1,n,l,r,k);
106         }
107     }
108     //system("pause");
109     return 0;
110 }
View Code

 

posted @ 2020-07-12 11:08  古比  阅读(170)  评论(0编辑  收藏  举报