题目链接:https://codeforces.com/problemset/problem/242/E
题目大意:
给你n和a[i]…a[n]。
m个操作:
1 l r 查询a[L]+…+a[R]
2 l r x
思路:我们用多棵树维护每一位就可以了。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
#define mid (l+r)/2
int a[100005];
int sum[21][400005], add[21][400005];
void BT(int rt, int l, int r, int x){
if(l==r){
sum[x][rt]=(a[l]&(1<<x))?1:0;
return ;
}
BT(rt<<1, l, mid, x);
BT((rt<<1)+1, mid+1, r, x);
sum[x][rt]=sum[x][rt<<1]+sum[x][(rt<<1)+1];
}
void GXdown(int rt, int x, int Le, int Re){
add[x][rt<<1]+=add[x][rt];
add[x][(rt<<1)+1]+=add[x][rt];
if(add[x][rt]%2){
sum[x][rt<<1]=Le-sum[x][rt<<1];
sum[x][(rt<<1)+1]=Re-sum[x][(rt<<1)+1];
}
add[x][rt]=0;
}
void GX(int rt, int l, int r, int L, int R, int x){
if(l==L&&r==R){
add[x][rt]+=1;
sum[x][rt]=(R-L+1)-sum[x][rt];
return ;
}
GXdown(rt, x, mid-l+1, r-mid);
if(R<=mid){
GX(rt<<1, l, mid, L, R, x);
}
else if(L>mid){
GX((rt<<1)+1, mid+1, r, L, R, x);
}
else{
GX(rt<<1, l, mid, L, mid, x);
GX((rt<<1)+1, mid+1, r, mid+1, R, x);
}
sum[x][rt]=sum[x][rt<<1]+sum[x][(rt<<1)+1];
}
int Q(int rt, int l, int r, int L, int R, int x){
if(l==L&&R==r){
return sum[x][rt];
}
GXdown(rt, x, mid-l+1, r-mid);
if(R<=mid){
return Q(rt<<1, l, mid, L, R, x);
}
else if(L>mid){
return Q((rt<<1)+1, mid+1, r, L, R, x);
}
else{
return Q(rt<<1, l, mid, L, mid, x)+Q((rt<<1)+1, mid+1, r, mid+1, R, x);
}
}
int main(){
int n, m;
scanf("%d", &n);
for(int i=1; i<=n; i++){
scanf("%d", &a[i]);
}
for(int i=0; i<=20; i++){
BT(1, 1, n, i);
}
scanf("%d", &m);
while(m--){
int k, l, r, x;
scanf("%d", &k);
if(k==1){
scanf("%d%d", &l, &r);
LL ans=0;
for(int i=0; i<=20; i++){
ans+=Q(1, 1, n, l, r, i)*(1ll<<i);
}
printf("%lld\n", ans);
}
else{
scanf("%d%d%d", &l, &r, &x);
for(int i=0; i<=20; i++){
if(x&(1<<i)){
GX(1, 1, n, l, r, i);
}
}
}
}
return 0;
}