求助,线段树,longlong已开,空间足够,仍然wa在15
查看原帖
求助,线段树,longlong已开,空间足够,仍然wa在15
912469
tutuwizard楼主2024/9/24 23:19
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5e5+100;
int n,q;
int a[N];
int b[N][22];
int tree[N>>2][22];
int tag[N>>2][22];
 
vector<int> getwo(int x){
	vector<int> ve;
	while(x){
		ve.push_back(x%2);
		x/=2;
	}
	return ve;
}
 
 
void build(int k,int l=1,int r=n,int p=1){
	if(l == r){
		tree[p][k] = b[l][k];
	}
	else{
		int mid = l+r >> 1;
		build(k,l,mid,p*2);
		build(k,mid+1,r,p*2+1);
		
		tree[p][k] =  tree[p*2][k] + tree[p*2+1][k];
	}
}
void update(int l,int r,int d,int k,int p=1,int cl=1,int cr=n){
	if(r < cl || l > cr){
		return ;
	}
	else if(cl >= l && cr <= r){
		if(d==1)
		tree[p][k] = cr - cl + 1 - tree[p][k];
		if(cr > cl){
			tag[p][k] = tag[p][k] ^ d;
		}
	}
	else{
		int mid = cl + cr >> 1;
		tag[p*2][k] = tag[p*2][k] ^ tag[p][k];
		tag[p*2+1][k] = tag[p*2+1][k] ^ tag[p][k];
		if(tag[p][k] == 1)
		tree[p*2][k] = mid - cl + 1 - tree[p*2][k];
		if(tag[p][k] == 1)
		tree[p*2+1][k] = cr - mid - tree[p*2+1][k];
		tag[p][k] = 0;
		
		update(l,r,d,k,p*2,cl,mid);
		update(l,r,d,k,p*2+1,mid+1,cr);
		
		tree[p][k] = tree[p*2][k] + tree[p*2+1][k];
	}
}
 
int query(int l,int r,int k,int p=1,int cl=1,int cr=n){
	if(r < cl || l > cr){
		return 0;
	}
	else if(cl >= l && cr <= r){
        return tree[p][k];
	}
	else{
		int mid = cl + cr >> 1;
		
		tag[p*2][k] = tag[p*2][k] ^ tag[p][k];
		tag[p*2+1][k] = tag[p*2+1][k] ^ tag[p][k];
		if(tag[p][k] == 1)
		tree[p*2][k] = mid - cl + 1 - tree[p*2][k];
		if(tag[p][k] == 1)
		tree[p*2+1][k] = cr - mid - tree[p*2+1][k];
		tag[p][k] = 0;
		
		return query(l,r,k,p*2,cl,mid) + query(l,r,k,p*2+1,mid+1,cr);
	}
}
 
signed main(){
	
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		auto y = getwo(a[i]);
		for(int j=0;j<y.size();j++){
			b[i][j] = y[j];
		}
	}
	
	for(int i=0;i<=21;i++){
		build(i);
	}
	
	cin>>q;
	while(q--){
		int op,l,r;
		cin>>op>>l>>r;
		if(op==1){
			 int ans = 0;
			 int now = 1;
			 for(int i=0;i<=21;i++){
			 	ans += query(l,r,i)*now;
			 	now*=2;
			 }
			 cout<<ans<<"\n"; 
		}
		else{
			int x;
			cin>>x;
			auto y = getwo(x);
            for(int i=0;i<y.size();i++){
            	if(y[i] == 1)
            	update(l,r,1,i);
			}
		}
	}
	
	return 0;
} 
2024/9/24 23:19
加载中...