[SPOJ1716] GSS3 - Can you answer these queries III

线段树操作。
维护一个区间最大连续子段和,左最大连续子段和,右最大连续子段和即可。
最后不知道怎么搞,query的时候返回了个结构体。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N=50005;
int n,q,a[N],opt,x,y;
struct Segtree{int l,r,lmx,rmx,mx,sum;}t[N<<3];
void pushup(int cur){
	t[cur].sum=t[cur<<1].sum+t[cur<<1|1].sum;
	t[cur].lmx=max(t[cur<<1].sum+t[cur<<1|1].lmx,t[cur<<1].lmx);
	t[cur].rmx=max(t[cur<<1|1].sum+t[cur<<1].rmx,t[cur<<1|1].rmx);
	t[cur].mx=max(t[cur<<1].mx,max(t[cur<<1|1].mx,t[cur<<1].rmx+t[cur<<1|1].lmx));
}
void build(int cur,int l,int r){
	t[cur].l=l,t[cur].r=r;
	if(l==r) {t[cur].sum=t[cur].rmx=t[cur].lmx=t[cur].mx=a[l];return;}
	int mid=l+r>>1;
	build(cur<<1,l,mid);
	build(cur<<1|1,mid+1,r);
	pushup(cur);
}
void update(int cur,int c,int now) {
	if(t[cur].l==t[cur].r) {t[cur].sum=t[cur].lmx=t[cur].rmx=t[cur].mx=c;return;}
	int mid=t[cur].l+t[cur].r>>1;
	if(now<=mid) update(cur<<1,c,now);
	else update(cur<<1|1,c,now);
	pushup(cur);
}
Segtree query(int l,int r,int cur) {
	if(l<=t[cur].l&&t[cur].r<=r) return t[cur];
	int mid=t[cur].l+t[cur].r>>1;
	if(l>mid) return query(l,r,cur<<1|1);
	if(r<=mid) return query(l,r,cur<<1);
	Segtree x=query(l,r,cur<<1),y=query(l,r,cur<<1|1),ans;
	ans.mx=max(x.mx,max(y.mx,x.rmx+y.lmx));
	ans.lmx=max(x.lmx,x.sum+y.lmx);
	ans.rmx=max(x.rmx+y.sum,y.rmx);
	return ans;
}
int main() {
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	scanf("%d",&q);
	build(1,1,n);
	while(q--) {
		scanf("%d%d%d",&opt,&x,&y);
		if(opt) printf("%d\n",query(x,y,1).mx);
		else update(1,y,x);
	}
	return 0;
}
posted @ 2018-07-11 19:30  SWHsz  阅读(108)  评论(0编辑  收藏  举报