样例一过不去,已调吐,玄关
查看原帖
样例一过不去,已调吐,玄关
499140
3wykx楼主2023/12/21 14:08
#include <bits/stdc++.h>
#define MAXN 1000005
#define INF 1000000000005
typedef long long lol;
using namespace std;
int n,q,l,r,op;
lol a[MAXN],delta;
struct node{
	int l,r;
	lol lazy1=INF,lazy2=0,val; //lazy1是修改,lazy2是加 
}tree[MAXN];
lol max(lol x,lol y){return x>y?x:y;}
void make_tree(int now,int ll,int rr){
	tree[now].l=ll,tree[now].r=rr;
	if(tree[now].l==tree[now].r){
		tree[now].val=a[now];
		return ;
	}
	int mid=(ll+rr)>>1;
	make_tree(now<<1,ll,mid);
	make_tree(now<<1|1,mid+1,rr);
	tree[now].val=max(tree[now<<1].val,tree[now<<1|1].val);
}
void down_tag(int x){
	if(tree[x].lazy1!=INF){
        tree[x<<1].lazy2=0;
        tree[x<<1].lazy1=tree[x].lazy1;
        tree[x<<1].val=tree[x].lazy1;
        tree[x<<1|1].lazy2=0;
        tree[x<<1|1].lazy1=tree[x].lazy1;
        tree[x<<1|1].val=tree[x].lazy1;
        tree[x].lazy1=INF;
    }
    if(tree[x].lazy2){
        tree[x<<1].lazy2+=tree[x].lazy2;
        tree[x<<1].val+=tree[x].lazy2;
        tree[x<<1|1].lazy2+=tree[x].lazy2;
        tree[x<<1|1].val+=tree[x].lazy2;
        tree[x].lazy2=0;
    }
}
lol query_interval(int now,int ll,int rr){
	if(tree[now].l>=ll&&tree[now].r<=rr)return tree[now].val;
	down_tag(now);
	int mid=(tree[now].l+tree[now].r)>>1;lol w=-INF;
	if(ll<=mid)w=max(w,query_interval(now<<1,ll,rr));
	if(r>mid)w=max(w,query_interval(now<<1|1,ll,rr));
	return w;
}
void change_interval(int now,int ll,int rr,int d){
	if(tree[now].l>=ll&&tree[now].r<=rr){
		tree[now].lazy2=0;
		tree[now].lazy1=d;
		tree[now].val=d; 
		return ;
	}
	down_tag(now);
	int mid=(tree[now].l+tree[now].r)>>1;
	if(ll<=mid)change_interval(now<<1,ll,rr,d);
	if(rr>mid)change_interval(now<<1|1,ll,rr,d);
	tree[now].val=max(tree[now<<1].val,tree[now<<1|1].val);
}
void add_interval(int now,int ll,int rr,int d){
	if(tree[now].l>=ll&&tree[now].r<=rr){
		tree[now].lazy2+=d;
		tree[now].val+=d; 
		return ;
	}
	down_tag(now);
	int mid=(tree[now].l+tree[now].r)>>1;
	if(ll<=mid)change_interval(now<<1,ll,rr,d);
	if(rr>mid)change_interval(now<<1|1,ll,rr,d);
	tree[now].val=max(tree[now<<1].val,tree[now<<1|1].val);
}
int main(){
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	make_tree(1,1,n);
	while(q--){
		scanf("%d%d%d",&op,&l,&r);
		if(op!=3)scanf("%lld",&delta);
		if(op==1)
			change_interval(1,l,r,delta);
		else if(op==2)
			add_interval(1,l,r,delta);
		else
			cout<<query_interval(1,l,r)<<endl;
	}
	return 0;
}
2023/12/21 14:08
加载中...