242E.XOR on segment(线段树维护区间异或)

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return x*f;
}

const int maxn=2e5+100;
int a[maxn];
int n,m,tot;
long long c[maxn<<2][30],lz[maxn<<2];
void build (int i,int l,int r) {
	if (l==r) {
		int bit=0;
		while (a[l]) {
			c[i][bit]+=a[l]%2;
			c[i][bit]%=2;
			a[l]/=2;
			bit++;
		}
		return;
	}
	int mid=(l+r)>>1;
	build(i<<1,l,mid);
	build(i<<1|1,mid+1,r);
	for (int j=0;j<=20;j++) c[i][j]=c[i<<1][j]+c[i<<1|1][j];
}
void spread (int i,int l,int r) {
	int mid=(l+r)>>1;
	if (lz[i]) {
		lz[i<<1]^=lz[i];
		lz[i<<1|1]^=lz[i];
		int bit=0;
		while (lz[i]) {
			int x=lz[i]%2;
			lz[i]/=2;
			if (x==1) c[i<<1][bit]=mid-l+1-c[i<<1][bit],c[i<<1|1][bit]=r-mid-c[i<<1|1][bit];
			bit++;
		}
	}
}
void up (int i,int l,int r,int L,int R,int x) {
	//这个区间的数与 
	if (l>=L&&r<=R) {
		lz[i]^=x;
		int bit=0;
		while (x) {
			int y=x%2;
			x/=2;
			if (y) c[i][bit]=r-l+1-c[i][bit];
			bit++;
		}
		return;
	}
	spread(i,l,r);
	int mid=(l+r)>>1;
	if (L<=mid) up(i<<1,l,mid,L,R,x);
	if (R>mid) up(i<<1|1,mid+1,r,L,R,x);
	for (int j=0;j<=20;j++) c[i][j]=c[i<<1][j]+c[i<<1|1][j];
}
long long query (int i,int l,int r,int L,int R) {
	if (l>=L&&r<=R) {
		long long bit=1;
		long long ans=0;
		for (int j=0;j<=20;j++) {
			ans+=c[i][j]*bit;
			bit*=2;
		}
		return ans;
	}
	spread(i,l,r);
	int mid=(l+r)>>1;
	long long ans=0;
	if (L<=mid) ans+=query(i<<1,l,mid,L,R);
	if (R>mid) ans+=query(i<<1|1,mid+1,r,L,R);
	return ans;
}
int main () {
	n=read();
	for (int i=1;i<=n;i++) a[i]=read();
	build(1,1,n);
	m=read();
	while (m--) {
		int op;
		op=read();
		if (op==1) {
			int l=read(),r=read();
			printf("%lld\n",query(1,1,n,l,r));
		}
		else {
			int l=read();
			int r=read();
			int x=read();
			up(1,1,n,l,r,x);
		}
	}
}
posted @ 2021-05-23 00:46  zlc0405  阅读(80)  评论(0编辑  收藏  举报