为 P4513 小白逛公园 降青默哀3分钟

这题是之前我A的第一道蓝题,也是我线段树的第3道题,在后续的题目中老师经常提到这题,这题是一个典型的线段树。
P4513 小白逛公园

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10; 
struct node{
	int l,r,sum,maxa,maxl,maxr;
};
node t[N*4];
int a[N];
void push_up(int u){
	t[u].sum=t[u*2].sum+t[u*2+1].sum;
	t[u].maxa=max(t[u*2].maxa,t[u*2+1].maxa);
	t[u].maxa=max(t[u].maxa,t[u*2].maxr+t[u*2+1].maxl);
	t[u].maxl=max(t[u*2].maxl,t[u*2].sum+t[u*2+1].maxl);
	t[u].maxr=max(t[u*2+1].maxr,t[u*2+1].sum+t[u*2].maxr);
} 
void build(int u,int l,int r){
	t[u].l=l,t[u].r=r;
	if(l==r){
		t[u].maxa=a[l];
		t[u].sum=a[l];
		t[u].maxl=t[u].maxr=a[l];
		return ;
	}
	int mid=(l+r)/2;
	build(u*2,l,mid);
	build(u*2+1,mid+1,r);
	push_up(u);
}
void update(int u,int l,int v){
	if(t[u].l==l&&t[u].r==l){
		t[u].maxa=v;
		t[u].sum=v;
		t[u].maxl=t[u].maxr=v;
		return ;
	}
	int mid=(t[u].l+t[u].r)/2;
	if(l<=mid) update(u*2,l,v);
	else update(u*2+1,l,v);
	push_up(u);
}
node query(int u,int l,int r){
	if(l<=t[u].l&&t[u].r<=r){
		return t[u];
	}
	int mid=(t[u].l+t[u].r)/2;
	if(l<=mid&&mid<r){
		node ans;
		node lq=query(u*2,l,r);
		node rq=query(u*2+1,l,r);
		ans.sum=lq.sum+rq.sum;
		ans.maxa=max(lq.maxa,rq.maxa);
		ans.maxa=max(ans.maxa,lq.maxr+rq.maxl);
		ans.maxl=max(lq.maxl,lq.sum+rq.maxl);
		ans.maxr=max(rq.maxr,rq.sum+lq.maxr);
		return ans;
	}else if(l<=mid) return query(u*2,l,r);
	else return query(u*2+1,l,r);
}
signed main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	} 
	build(1,1,n);
	while(m--){
		int opt;
		cin>>opt;
		if(opt==1){
			int x,y;
			cin>>x>>y;
			if(x>y) swap(x,y);
			cout<<query(1,x,y).maxa<<endl;
		} else{
			int x,y;
			cin>>x>>y;
			update(1,x,y); 
		}
	}
	return 0;
}

posted @ 2026-08-06 16:33  ThomasHang  阅读(4)  评论(0)    收藏  举报