P4513 小白逛公园(线段树)

pushup:t[k].max=max(t[k<<1].max,t[k<<1|1].max,t[k<<1].rmax+t[k<<1|1].lmax);

注意查询,如果所要找的区间恰好在左区间或右区间中,则直接查找。否则和pushup中一样操作。

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=500005;
ll a[N];
int n,m;
ll read(){
	ll num=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		num=num*10+c-'0';
		c=getchar();
	}
	return num*f;
}
struct node{
	ll lmax,rmax,sum,max;
}t[N<<2];
ll maxx(ll x,ll y,ll z){
	return max(x,max(y,z));
}
void pushup(int k){
	t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
	t[k].lmax=max(t[k<<1].lmax,t[k<<1].sum+t[k<<1|1].lmax);
	t[k].rmax=max(t[k<<1|1].rmax,t[k<<1].rmax+t[k<<1|1].sum);
	t[k].max=maxx(t[k<<1].max,t[k<<1|1].max,t[k<<1].rmax+t[k<<1|1].lmax);
}
void build(int k,int l,int r){
	if(l==r){
		t[k].max=t[k].sum=t[k].lmax=t[k].rmax=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	pushup(k);
}
node query(int k,int l,int r,int x,int y){
	if(x<=l&&r<=y){
		return t[k];
	}
	int mid=(l+r)>>1;
	if(y<=mid) return query(k<<1,l,mid,x,y);
	else if(x>mid) return query(k<<1|1,mid+1,r,x,y);
	else{
		node a=query(k<<1,l,mid,x,y),b=query(k<<1|1,mid+1,r,x,y);
		node tmp;
		tmp.sum=a.sum+b.sum;
		tmp.lmax=max(a.lmax,a.sum+b.lmax);
		tmp.rmax=max(b.rmax,b.sum+a.rmax);
		tmp.max=maxx(a.max,b.max,a.rmax+b.lmax);
		return tmp;
	}
}
void update(int k,int l,int r,int x,int v){
	if(l==r){
		t[k].max=t[k].lmax=t[k].rmax=t[k].sum=v;
		return; 
	}
	int mid=(l+r)>>1;
	if(x<=mid) update(k<<1,l,mid,x,v);
	if(x>mid) update(k<<1|1,mid+1,r,x,v);
	pushup(k);
}
int main(){
	n=read(); m=read();
	for(int i=1;i<=n;i++) a[i]=read();
	build(1,1,n);
	for(int i=1;i<=m;i++){
		ll k=read(),a=read(),b=read();
		if(k==1){
			if(a>b) swap(a,b);
			printf("%lld
",query(1,1,n,a,b).max);
		}
		else{
			update(1,1,n,a,b);
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/New-ljx/p/15339230.html