线段树 20pts 玄关求调
查看原帖
线段树 20pts 玄关求调
846713
Joker_IV楼主2024/10/30 19:03

代码如下(AC #1 # 3)

#include <bits/stdc++.h>
using namespace std;
#define MAXN 8000010
#define int long long
#define zero -1e17
long long a[MAXN],t[MAXN],lzy[MAXN],n,q,cover[MAXN];
bool inrange(int L,int R,int l,int r){
	return l<=L&&R<=r;
}
bool outrange(int L,int R,int l,int r){
	return(l>R||r<L);
}
void build(const int u,int L,int R){
	if(L==R){
		t[u]=a[L];
		cover[u]=a[L];
		lzy[u]=0;
		return;
	}
	int mid=(R+L)>>1;
	build(u*2,L,mid);build(u*2+1,mid+1,R);
	t[u]=max(t[u*2],t[u*2+1]);
}
void maketag(int u,long long k,int type){
	if(type==1){
		t[u]=k;
		cover[u]=k;
		lzy[u]=0;
	}
	else{
		t[u]+=k;
		if(cover[u]==zero){
			lzy[u]+=k;
		}
		else{
			cover[u]+=k;
		}
	}
	
}
void pushdown(int u){
	if(cover[u]!=zero){
		maketag(u*2,cover[u],1);
		maketag(u*2+1,cover[u],1);
		cover[u]=zero;
	}
	else if(lzy[u]){
		maketag(u*2,lzy[u],2);
		maketag(u*2+1,lzy[u],2);
		lzy[u]=0;
	}
}
void update(int u,int L,int R,int l,int r,int k,int type){
	if(inrange(L,R,l,r) && cover[u] != zero){
		maketag(u,k,type);
		return;
	}
	if(!outrange(L,R,l,r)){
		int mid=(L+R)/2;
		pushdown(u);
		update(u*2,L,mid,l,r,k,type);update(u*2+1,mid+1,R,l,r,k,type);
		t[u]=max(t[u*2],t[u*2+1]);
	}
}
long long ask(int u,int L,int R,int l,int r){
	if(inrange(L,R,l,r))return t[u];
	if(!outrange(L,R,l,r)){
		int mid=(L+R)/2, ma = zero;
		pushdown(u);
		if (mid >=l)ma = max(ma, ask(u*2,L,mid,l,r));
		if (mid <r) ma = max(ma,ask(u*2+1,mid+1,R,l,r));
		return ma;
	}
	else return zero;
}
signed main(){
	freopen("1.in", "r", stdin);
	scanf("%lld%lld",&n,&q);
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	build(1,1,n);
	while(q--){
		int x,y,k;
		int op;
		scanf("%d%d%d",&op,&x,&y);
		if(op==1||op==2){
			scanf("%d",&k);
			update(1,1,n,x,y,k,op);
		}
		else if(op==3){
			printf("%lld\n",ask(1,1,n,x,y));
		}
		
	}
	return 0;
}
2024/10/30 19:03
加载中...