线段树MLE求调
查看原帖
线段树MLE求调
775277
xiongzecheng楼主2024/1/25 17:34
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,a[400005],q;
ll p[400005][25],sum[400005][25],L[400005][25],R[400005][25],lazy[400005][25];
//每个数组每一维都是一个线段树 
void ding(ll k,ll y,ll wz){
	p[k][wz]=y;
}
ll len(ll x,ll wz){
	return R[x][wz]-L[x][wz]+1;
}
void push_up(ll x,ll wz){
	sum[x][wz]=sum[x*2][wz]+sum[x*2+1][wz];
}
void push_down(ll x,ll wz){
	if(lazy[x][wz]){
		lazy[x*2][wz]^=1;lazy[x*2+1][wz]^=1;
		sum[x*2][wz]=len(x*2,wz)-sum[x*2][wz];
		sum[x*2+1][wz]=len(x*2+1,wz)-sum[x*2+1][wz];
		lazy[x][wz]=0;
	}
}
void build(ll l,ll r,ll x,ll wz){
	L[x][wz]=l,R[x][wz]=r;
	if(l==r){
		sum[x][wz]=p[l][wz];return;
	}
	ll mid=(l+r)/2;
	build(l,mid,x*2,wz);
	build(mid+1,r,x*2+1,wz);
	push_up(x,wz);
}
void update(ll l,ll r,ll x,ll zhi,ll wz){
	if(l<=L[x][wz]&&R[x][wz]<=r){
		lazy[x][wz]^=zhi;
		if(zhi)sum[x][wz]=len(x,wz)-sum[x][wz];
		return;
	}
	push_down(x,wz);
	ll mid=(L[x][wz]+R[x][wz])/2;
	if(l<=mid)update(l,r,x*2,zhi,wz);
	if(mid<r)update(l,r,x*2+1,zhi,wz);
	push_up(x,wz);
}
ll query(ll l,ll r,ll x,ll wz){
	if(l<=L[x][wz]&&R[x][wz]<=r)return sum[x][wz];
	push_down(x,wz);
	ll ans=0,mid=(L[x][wz]+R[x][wz])/2;
	if(l<=mid)ans+=query(l,r,x*2,wz);
	if(mid<r)ans+=query(l,r,x*2+1,wz);
	return ans;
}
//以上是线段树的过程,其中参数wz代表第i位的线段树 
ll ask(ll a,ll x){
	ll cnt=0;
	while(cnt<x)a/=2,cnt++;
	return a&1;
}
//查询a在二进制下右数第x位的值 
int main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	for(int i=0;i<=20;i++)
		for(int j=1;j<=n;j++)
			ding(j,ask(a[j],i),i);
	for(int i=0;i<=20;i++)build(1,n,1,i);
	scanf("%lld",&q);
	while(q--){
		ll op,l,r,x;scanf("%lld",&op);
		if(op==1){
			scanf("%lld%lld",&l,&r);
			ll ans=0;
			for(int i=0;i<=20;i++)ans+=(1ll<<i)*query(l,r,1,i);
			printf("%lld\n",ans);
		}
		if(op==2){
			scanf("%lld%lld%lld",&l,&r,&x);
			for(int i=0;i<=20;i++)
				update(l,r,1,ask(x,i),i);
		}
	}
	return 0;
}
2024/1/25 17:34
加载中...