區間或+區間和

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 2e5 + 5;
const int INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
struct node{
	int w[20];//二進制 20 位 
	int lazy;
}tree[maxn*4];
int a[maxn];
void push(int p){
	for(int i=0;i<20;i++){//這N個數的第I位有多少個1 
		tree[p].w[i]=tree[p<<1].w[i]+tree[p<<1|1].w[i];
	}
}
void get(int l,int r,int p,int val){
	for(int i=0;i<20;i++){
		if(val&(1<<i)){//判斷這個位置是否是1 
			tree[p].w[i]=(r-l+1);//這N個數的第I位有多少個1 
		}
	}
}
void pushdown(int l,int r,int p){
	int mid=(l+r)/2;
	if(tree[p].lazy){
		tree[p<<1].lazy|=tree[p].lazy;
		tree[p<<1|1].lazy|=tree[p].lazy;
		get(l,mid,p<<1,tree[p].lazy);
		get(mid+1,r,p<<1|1,tree[p].lazy);
		tree[p].lazy=0;
	}
}
void build(int l,int r,int p){
	if(l==r){
		for(int i=0;i<20;i++)
		   if(a[l]&(1<<i))//當前位是1 
		        tree[p].w[i]=1;
		   else tree[p].w[i]=0;
	    return;   
	}
	int mid=(l+r)/2;
	build(l,mid,p<<1);
	build(mid+1,r,p<<1|1);
	push(p);
}
void update(int l,int r,int L,int R,int val,int p){
	if(L<=l&&r<=R){
		get(l,r,p,val);
		tree[p].lazy|=val;
		return ;
	}
	pushdown(l,r,p);
	int mid=(l+r)/2;
	if(L<=mid) update(l,mid,L,R,val,p<<1);
	if(R>mid) update(mid+1,r,L,R,val,p<<1|1);
	push(p);
}

ll query(int l,int r,int L,int R,int p){
	if(L<=l&&r<=R){//區間和 
		ll tmp=1; ll res=0;
		for(int i=0;i<20;i++){
			res+=tmp*tree[p].w[i];//該區間所有這1位有多少個1 
			tmp=tmp*2;
		}
		return res;
	}
	pushdown(l,r,p);
	int mid=(l+r)/2;
	ll ans=0;
	if(L<=mid) ans+=query(l,mid,L,R,p<<1);
	if(R>mid) ans+=query(mid+1,r,L,R,p<<1|1);
	return ans;
}
int main(){
	int n; scanf("%d",&n);
	int q; scanf("%d",&q);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	build(1,n,1);
	while(q--){
		char s[5]; scanf("%s",s);
		if(s[0]=='S'){
			int x,y; scanf("%d %d",&x,&y);
			ll ans=query(1,n,x,y,1);
			printf("%lld\n",ans);
		}else{
			int x,y,val;
			scanf("%d %d %d",&x,&y,&val);
			update(1,n,x,y,val,1);
		}
	}
	return 0;
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章