线段树求调
查看原帖
线段树求调
373198
WhileTrueRP楼主2023/11/5 07:37
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1e5+5;
struct node{
	int sum,l,r,lazy;
}tree[25][N];
int a[N];
int b[25][N];
void init(int l,int r,int p){
	for(int i=1;i<=20;i++){
		tree[i][p].l = l;
		tree[i][p].r = r;
	}
	if(l == r){
		for(int i=1;i<=20;i++){
			tree[i][p].sum = b[i][l];
		}
		return;
	}
	int mid = (l+r)>>1;
	init(l,mid,p<<1);
	init(mid+1,r,p<<1|1);
	for(int i=1;i<=20;i++){
		tree[i][p].sum = tree[i][p<<1].sum + tree[i][p<<1|1].sum;
	}
	return;
}
void pushdown(int c,int p){
	if(tree[c][p].lazy){
		tree[c][p].sum = tree[c][p].r - tree[c][p].l + 1 - tree[c][p].sum;
		
		tree[c][p<<1].lazy ^= 1;
		tree[c][p<<1|1].lazy ^= 1;
		
		tree[c][p].lazy = 0;
	}
	return;
}
int query(int l,int r,int c,int p){
	if(tree[c][p].l == l && tree[c][p].r == r){
		return (tree[c][p].lazy == 0)?tree[c][p].sum:(tree[c][p].r-tree[c][p].l+1-tree[c][p].sum);
	}
	pushdown(c,p);
	if(tree[c][p<<1].r >= r){
		return query(l,r,c,p<<1);
	}else if(tree[c][p<<1|1].l <= l){
		return query(l,r,c,p<<1|1);
	}else{
		return query(l,tree[c][p<<1].r,c,p<<1) + query(tree[c][p<<1|1].l,r,c,p<<1|1);
	}
}
void change(int l,int r,int c,int p){
	if(tree[c][p].l == l && tree[c][p].r == r){
		tree[c][p].lazy ^= 1;
		return;
	}
	pushdown(c,p);
	if(tree[c][p<<1].r >= r){
		change(l,r,c,p<<1);
	}else if(tree[c][p<<1|1].l <= l){
		change(l,r,c,p<<1|1);
	}else{
		change(l,tree[c][p<<1].r,c,p<<1);
		change(tree[c][p<<1|1].l,r,c,p<<1|1);
	}
	tree[c][p].sum = 
		(tree[c][p<<1].lazy == 0)
		?(tree[c][p<<1].sum):
		(tree[c][p<<1].r-tree[c][p<<1].l+1-tree[c][p<<1].sum) +
		(tree[c][p<<1|1].lazy == 0)
		?(tree[c][p<<1|1].sum):
		(tree[c][p<<1|1].r-tree[c][p<<1|1].l+1-tree[c][p<<1|1].sum);
}
int main(){
	int n,m,opt,l,r,x;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n;i++){
		int j = 1;
		while(a[i]){
			b[j][i] = a[i] & 1;
			a[i] >>= 1;
			j++;
		}
	}
	init(1,n,1);
	scanf("%d",&m);
	for(int i=1;i<=m;i++){
		scanf("%d",&opt);
		if(opt == 1){
			scanf("%d%d",&l,&r);
			int ans = 0;
			for(int i=20;i>=1;i--){
				ans += (query(l,r,i,1)<<(i-1));
			}
			printf("%d\n",ans);
		}else if(opt == 2){
			scanf("%d%d%d",&l,&r,&x);
			int j = 1;
			while(x){
				if(x&1){
//					printf("~%d~",j);
					change(l,r,j,1);
				}
				j ++;
				x >>= 1;
			}
		}
	}
}
2023/11/5 07:37
加载中...