代码求助
查看原帖
代码求助
983702
lrj3247楼主2024/8/30 20:40

蒟蒻没看题解yy的思路:因为是异或,所以可以按位统计贡献,于是设x[i]为区间内第i为1的个数,sum为和,tag[i]为异或的第i位的lazytag。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+15;
int n,m,arr[N],now[20];
ll a[N][20];
struct Tree{
	int l,r;
	ll x[20],sum,tag[20];
	Tree(){
		l=r=sum=0;
		memset(tag,0,sizeof(tag));
		memset(x,0,sizeof(x));
	}
}tr[N<<2];
inline int read(){
	int w=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while('0'<=ch&&ch<='9'){
		w=w*10+ch-'0';
		ch=getchar();
	}
	return w*f;
}
inline void write(int x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
inline void pre(int now,int x){
	int j = 21;
	while(x>0){
		a[now][--j]=(x&1);
		x>>=1;
	}
}
inline void pushup(Tree &fa,Tree &ls,Tree &rs){
	for(int i = 0 ; i<20 ; i++) fa.x[i]=ls.x[i]+rs.x[i];
	fa.sum=ls.sum+rs.sum;
}
inline void pushdown(Tree &fa,Tree &ls,Tree &rs){
	ls.sum=0,rs.sum=0;
	for(int i = 0 ; i<20 ; i++){
		int tmp=fa.tag[i];
		if(tmp){
			ls.x[i]=ls.r-ls.l+1-ls.x[i];
			rs.x[i]=rs.r-rs.l+1-rs.x[i];
		}
		ls.sum+=ls.x[i];
		rs.sum+=rs.x[i];
		ls.tag[i]=tmp,rs.tag[i]=tmp;
		fa.tag[i]=0;
	}
	return ;
}
void build(int id,int l,int r){
	tr[id].l=l,tr[id].r=r,tr[id].sum=0;
	if(l==r){
		for(int i = 0 ; i<20 ; i++)
		tr[id].x[i]=a[l][i];
		tr[id].sum=arr[l];
		return ;
	}
	int mid=l+r>>1;
	build(id<<1,l,mid);
	build(id<<1|1,mid+1,r);
	pushup(tr[id],tr[id<<1],tr[id<<1|1]);
}
void modify(int id,int x,int y,int k){
	int l=tr[id].l,r=tr[id].r;
	if(x<=l&&r<=y){
		int len=r-l+1;
		tr[id].sum=0;
		for(int i = 0 ; i<20 ; i++){
			if(now[i])
			tr[id].x[i]=len-tr[id].x[i];
			tr[id].tag[i]^=now[i];
			tr[id].sum+=tr[id].x[i];
		}
	}
	pushdown(tr[id],tr[id<<1],tr[id<<1|1]);
	int mid=l+r>>1;
	if(x<=mid) modify(id<<1,x,y,k);
	if(y>mid) modify(id<<1|1,x,y,k);
	pushup(tr[id],tr[id<<1],tr[id<<1|1]);
}
ll query(int id,int x,int y){
	int l=tr[id].l,r=tr[id].r;
	if(x<=l&&r<=y){
		return tr[id].sum;
	}
	pushdown(tr[id],tr[id<<1],tr[id<<1|1]);
	int mid=l+r>>1;
	long long ret=0;
	if(x<=mid) ret+=query(id<<1,x,y);
	if(y>mid) ret+=query(id<<1|1,x,y);
	return ret;
}
int main(){
	n=read();
	for(int i = 1 ; i<=n ; i++){
		arr[i] = read();
		pre(i,arr[i]);
	}
	build(1,1,n);
	m=read();
	for(int i = 1 ; i<=m ; i++){
		int op=read(),l=read(),r=read();
		if(op==1){
			write(query(1,l,r));
			putchar('\n');
		}
		else{
			memset(now,0,sizeof(now));
			int x=read();
			int j = 21;
			while(x>0){
				now[--j]=(x&1);
				x>>=1;
			}
			modify(1,l,r,x);
		}
	}
	return 0;
}
2024/8/30 20:40
加载中...