60pts求调/huck(有注释)(悬棺)
查看原帖
60pts求调/huck(有注释)(悬棺)
1054119
xzq4121楼主2024/7/11 17:01

代码如下:

#include <bits/stdc++.h>
using namespace std;
long long n,m,p[4000010],shu[4000010],q[4000010],v[1000010];//p是加法的懒标记,q是覆盖的懒标记,v是原数组 
void lan(long long h){
	if(q[h]!=-1e18){//-1e18是特殊值 
		shu[h*2]=q[h];//修改左儿子 
		shu[h*2+1]=q[h];//修改右儿子 
		q[h*2]=q[h*2+1]=q[h];//修改儿子的懒标记 
		q[h]=-1e18;//懒标记赋回特殊值 
		p[h*2]=0;//左儿子加法懒标记归零 
		p[h*2+1]=0;//右儿子加法懒标记归零 
	}
	else{
		shu[h*2]+=p[h];//修改左儿子 
		shu[h*2+1]+=p[h];//修改右儿子 
		p[h*2]+=p[h];//修改儿子的懒标记 
		p[h*2+1]+=p[h];//修改儿子的懒标记 
		p[h]=0;//懒标记赋归零
	}
}
void jianshu(long long s,long long t,long long b){//建树 
	if(s==t){
		shu[b]=v[s];
		return;
	}
	long long mid=(s+t)/2;
	jianshu(s,mid,b*2);
	jianshu(mid+1,t,b*2+1);
	shu[b]=max(shu[b*2],shu[b*2+1]);//计算最大值 
}
long long cha(long long l,long long r,long long s,long long t,long long h){//查询最大值 
	if(l<=s&&t<=r) return shu[h];//直接返回值 
	long long mid=(s+t)/2,ans=-1e18;//ans赋特殊值 
	if(q[h]!=-1e18||p[h]) lan(h);//判是否下传懒标记 
	if(l<=mid) ans=cha(l,r,s,mid,h*2);
	if(r>mid) ans=max(cha(l,r,mid+1,t,h*2+1),ans);
	return ans;
}
void jia(long long s,long long t,long long l,long long r,long long h,long long k){//区间加 
	if(l<=s&&t<=r){
		shu[h]+=k;
		if(q[h]!=-1e18){
			q[h]+=k+p[h];//直接把加法懒标记加到赋值懒标记 
			p[h]=0;
		} 
		else p[h]+=k;
		return;	
	}
	long long mid=(s+t)/2;
	if(p[h]&&s!=t) lan(h);//判是否下传懒标记 
	if(l<=mid) jia(s,mid,l,r,h*2,k);
	if(r>mid) jia(mid+1,t,l,r,h*2+1,k);
	shu[h]=max(shu[h*2],shu[h*2+1]);//计算最大值 
}
void gai(long long s,long long t,long long l,long long r,long long h,long long k){
	if(l<=s&&t<=r){
		shu[h]=k;
		q[h]=k;
		p[h]=0;//加法懒标记归零 
		return;
	}
	long long mid=(s+t)/2;
	if(s!=t&&q[h]!=-1e18) lan(h);//判是否下传懒标记 
	if(l<=mid) gai(s,mid,l,r,h*2,k);
	if(r>mid) gai(mid+1,t,l,r,h*2+1,k);
	shu[h]=max(shu[h*2],shu[h*2+1]);//计算最大值 
}
signed main(){
	scanf("%lld %lld",&n,&m);
	for(long long i=1;i<=n;i++) scanf("%lld",&v[i]);
	for(long long i=1;i<=4*n;i++) q[i]=-1e18;
	jianshu(1,n,1);
	for(long long i=1;i<=m;i++){
		long long a,b,c,d;
		scanf("%lld",&a);
		if(a==1){
			scanf("%lld %lld %lld",&b,&c,&d);
			gai(1,n,b,c,1,d);
		}
		else if(a==2){
			scanf("%lld %lld %lld",&b,&c,&d);
			jia(1,n,b,c,1,d);
		}
		else{
			scanf("%lld %lld",&b,&c);
			printf("%lld\n",cha(b,c,1,n,1));
		}
	}
	return 0;
} 
2024/7/11 17:01
加载中...