CH4301 Can you answer on these queries III

CH4301

维护一个序列,支持单点修改和查询区间\([x,y]\)中的最大连续子段和

问题在于如何维护最大连续字段和,或者说怎么存下最大连续子段和能让它满足区间加法,这也是用线段树维护某个东西时要考虑的核心问题

考虑最大连续字段和的形成方式,可能是整个区间\([l,r]\)的和,可能是紧靠\(l\)这边的一段连续和,可能是紧靠\(r\)这边的一段连续和

所以我们可以在线段树中额外维护区间和\(sum\),左端最大连续子段\(lmax\)和和右端连续子段和\(rmax\),以及最大连续字段和\(dat\)

只需要在从下往上更新的地方注意这几个量的关系,进行维护即可求解,转移的时候有点像区间\(dp\)

特别注意:此时如果\(x>y\),请交换\(x,y\)

#include<bits/stdc++.h>
using namespace std;
const int N=500010;
int n,m,a[N];
struct SegmentTree {
	int l,r,dat,lmax,rmax,sum;
} t[N<<2];
void build(int p,int l,int r) {
	t[p].l=l;
	t[p].r=r;
	if(l==r) {
		t[p].lmax=t[p].rmax=t[p].dat=t[p].sum=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid),build(p<<1|1,mid+1,r);
	t[p].dat=max(t[p<<1].rmax+t[p<<1|1].lmax,max(t[p<<1].dat,t[p<<1|1].dat));
	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
	t[p].lmax=max(t[p<<1].lmax,t[p<<1].sum+t[p<<1|1].lmax);
	t[p].rmax=max(t[p<<1|1].rmax,t[p<<1].rmax+t[p<<1|1].sum);
	return;
}
void update(int p,int x,int v) {
	if(t[p].l==t[p].r) {
		t[p].lmax=t[p].rmax=t[p].dat=t[p].sum=v;
		return;
	}
	int mid=(t[p].l+t[p].r)>>1;
	if(x<=mid) update(p<<1,x,v);
	else update(p<<1|1,x,v);
	t[p].dat=max(t[p<<1].rmax+t[p<<1|1].lmax,max(t[p<<1].dat,t[p<<1|1].dat));
	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
	t[p].lmax=max(t[p<<1].lmax,t[p<<1].sum+t[p<<1|1].lmax);
	t[p].rmax=max(t[p<<1|1].rmax,t[p<<1].rmax+t[p<<1|1].sum);
}
SegmentTree query(int p,int L,int R) {
	SegmentTree ret,tmpl,tmpr;
	if(L<=t[p].l&&t[p].r<=R) return t[p];
	int mid=(t[p].l+t[p].r)>>1;
	if(R<=mid) return query(p<<1,L,R);
	if(mid<L) return query(p<<1|1,L,R);
	tmpl=query(p<<1,L,R);
	tmpr=query(p<<1|1,L,R);
	ret.dat=max(tmpl.rmax+tmpr.lmax,max(tmpl.dat,tmpr.dat));
	ret.lmax=max(tmpl.lmax,tmpl.sum+tmpr.lmax);
	ret.rmax=max(tmpr.rmax,tmpr.sum+tmpl.rmax);
	ret.sum=tmpl.sum+tmpr.sum;
	return ret;
}
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) scanf("%d",&a[i]);
	build(1,1,n);
	while(m--) {
		int k,x,y;
		scanf("%d%d%d",&k,&x,&y);
		if(k==1) {
			if(x>y) swap(x,y);
			printf("%d\n",query(1,x,y).dat);
		} else update(1,x,y);
	}
	return 0;
}
posted @ 2020-07-05 14:00  pyyyyyy  阅读(149)  评论(4编辑  收藏  举报