社区讨论

50pts玄关求调

P1253扶苏的问题参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mhjoasdc
此快照首次捕获于
2025/11/04 05:49
4 个月前
此快照最后确认于
2025/11/04 05:49
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define ll long long
#define MAN 11451400
#define N 114514151515151
using namespace std;
ll n,m,q;
ll a[MAN],w[MAN];
ll la[MAN],lx[MAN];//la为加法标记,lx为覆盖标记
void pushup(const ll u){
	w[u]=max(w[u*2],w[u*2+1]);
}
void build(const ll u,ll l,ll r){
	lx[u]=-N;
	if(l==r){
		w[u]=a[l];
		return;
	}
	ll m=(l+r)/2;
	build(u*2,l,m);
	build(u*2+1,m+1,r);
	pushup(u);
}
bool in(ll L,ll R,ll l,ll r){
	return (L>=l)&&(R<=r);
}
bool out(ll L,ll R,ll l,ll r){
	return (L>r)||(R<l);
}
void maketag(ll u,ll x,ll opt){
	if(opt==1&&x!=-N){//opt 为1时做覆盖标记
		lx[u]=x;
		w[u]=x;
		la[u]=0;
	}
	if(opt==2){//opt为2时做加法标记
		if(lx[u]==-N) la[u]+=x;
		else lx[u]+=x;
		w[u]+=x;
	}
}
void pushdown(ll u){
	if(lx[u]==-N){
		maketag(u*2,la[u],2);
		maketag(u*2+1,la[u],2);
		la[u]=0;
	}
	if(lx[u]!=-N){
		maketag(u*2,lx[u],1);
		maketag(u*2+1,lx[u],1);
		lx[u]=-N;
		la[u]=0;
	}
}
ll query(ll u,ll L,ll R,ll l,ll r){
	if(in(L,R,l,r)) 
		return w[u];
	else if(!out(L,R,l,r)){
		ll m=(L+R)/2;
		pushdown(u);
		return max(query(u*2,L,m,l,r),query(u*2+1,m+1,R,l,r));
	}
	else return 0;
}
void update1(ll u,ll L,ll R,ll l,ll r,ll x){
	if(in(L,R,l,r))
		maketag(u,x,1);
	else if(!out(L,R,l,r)){
		ll m=(L+R)/2;
		pushdown(u);
		update1(u*2,L,m,l,r,x);
		update1(u*2+1,m+1,R,l,r,x);
		pushup(u);
	}
}
void update2(ll u,ll L,ll R,ll l,ll r,ll x){
	if(in(L,R,l,r))
		maketag(u,x,2);
	else if(!out(L,R,l,r)){
		ll m=(L+R)/2;
		pushdown(u);
		update2(u*2,L,m,l,r,x);
		update2(u*2+1,m+1,R,l,r,x);
		pushup(u);
	}
}
int main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	build(1,1,n);
	while(q--){
		ll opt,x,y,k;
		cin>>opt;
		if(opt==1){
			cin>>x>>y>>k;
			update1(1,1,n,x,y,k);
		}
		else if(opt==2){
			cin>>x>>y>>k;
			update2(1,1,n,x,y,k);
		}	
		else if(opt==3){
			cin>>x>>y;
			cout<<query(1,1,n,x,y)<<endl;
		}
	}
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...