求助悬关,线段树20pts,代码有注释
查看原帖
求助悬关,线段树20pts,代码有注释
892979
liuenyin楼主2023/7/30 21:42

AC on #1 and #3,代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long INF=0x7ffffffffffffff;
struct segment_tree{
	struct node{
		ll l,r,w;//w: max
		ll lazytag_1,lazytag_2;//懒标记 
		node(){
			lazytag_1=lazytag_2=-INF;
		} 
	};
	node tree[4000005];//线段树开4倍空间
	ll arr[1000005];
	void build(int l,int r,int p){
		//   左  右   根
		tree[p].l=l;
		tree[p].r=r; 
		if(l==r){
			tree[p].w=arr[l];
			//arr为原数组 
			return;
		}
		int mid=(l+r)/2;
		build(l,mid,p*2);//建立左子树
		build(mid+1,r,p*2+1);//建立右子树
		tree[p].w=max(tree[p*2].w,tree[p*2+1].w);
	} 
	void pushdown_1(int p){
		//懒标记下传(opt=1) 即将区间内的值设为x 
		if(tree[p].lazytag_1!=-INF){
			tree[p*2].w = tree[p].lazytag_1;
			tree[p*2+1].w=tree[p].lazytag_1;
			tree[p*2].lazytag_1=tree[p].lazytag_1;
			tree[p*2+1].lazytag_1=tree[p].lazytag_1;
			tree[p].lazytag_1=-INF;
		} 
	}
	void pushdown_2(int p){
		//懒标记下传(opt=2) 即将区间内的值增加x
		if(tree[p].lazytag_2!=-INF){
			tree[p*2].w+=tree[p].lazytag_2;
			tree[p*2+1].w+=tree[p].lazytag_2;
			tree[p*2].lazytag_2+=tree[p].lazytag_2;
			tree[p*2+1].lazytag_2+=tree[p].lazytag_2;
			tree[p].lazytag_2=-INF;
		} 
	}
	void update_1(int l,int r,int p,int x){
		//更新区间的值(opt=1)
		if(l<=tree[p].l and r>=tree[p].r){
			tree[p].w=x;
			tree[p].lazytag_1=x;
			return;
		} 
		pushdown_1(p);
		int mid=(tree[p].l+tree[p].r)/2;
		if(l<=mid)update_1(l,r,p*2,x);
		if(r>mid)update_1(l,r,p*2+1,x);
		tree[p].w=max(tree[p*2].w,tree[p*2+1].w);
	}
	void update_2(int l,int r,int p,int x){
		//更新区间的值 (opt=2)
		if(l<=tree[p].l and r>=tree[p].r){
			tree[p].w+=x;
			tree[p].lazytag_2+=x;
			return;
		} 
		pushdown_2(p);
		int mid=(tree[p].l+tree[p].r)/2;
		if(l<=mid)update_2(l,r,p*2,x);
		if(r>mid)update_2(l,r,p*2+1,x);
		tree[p].w=max(tree[p*2].w,tree[p*2+1].w);
	}
	ll query(int l,int r,int p){
		//查询区间的值
		if(l<=tree[p].l and r>=tree[p].r){
			return tree[p].w;
		} 
	//	pushdown_1(p);
		pushdown_2(p);
		ll mid=(tree[p].l+tree[p].r)/2,ans=-INF;
		if(l<=mid)ans=max(ans,query(l,r,p*2));
		if(r>mid)ans=max(ans,query(l,r,p*2+1));
		return ans;
	}
};

segment_tree t;
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		scanf("%lld",&t.arr[i]);
	}
	t.build(1,n,1);
	int op,l,r,x;
	for(int i=1;i<=m;i++){
		cin>>op>>l>>r;
		//cout<<op<<" "<<l<<" "<<r<<endl;
		if(op==1||op==2)cin>>x; 
		if(op==1){
			t.update_1(l,r,1,x);
		}
		else if(op==2){
			t.update_2(l,r,1,x);
		}
		else{
			cout<<t.query(l,r,1)<<endl;
		}
	}
	return 0;
}

2023/7/30 21:42
加载中...