为 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;
}

浙公网安备 33010602011771号