Spoj GSS3 - Can you answer these queries III

题目描述

You are given a sequence A of N (N <= 50000) integers between -10000 and 10000. On this sequence you have to apply M (M <= 50000) operations:
modify the i-th element in the sequence or for given x y print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.

输入输出格式

输入格式:

 

The first line of input contains an integer N. The following line contains N integers, representing the sequence A1..AN.
The third line contains an integer M. The next M lines contain the operations in following form:
0 x y: modify Ax into y (|y|<=10000).
1 x y: print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.

 

输出格式:

 

For each query, print an integer as the problem required.

 

输入输出样例

输入样例#1: 
4
1 2 3 4
4
1 1 3
0 3 -3
1 2 4
1 3 3
输出样例#1: 
6
4
-3


单点修改的最大子段和还是会的hhhh
每个节点维护四个值就行了。
注意查询的时候我们要用到当前区间左边的最大前缀。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define maxn 200005
using namespace std;
const int inf=1<<30;
int mx[maxn],mxl[maxn];
int mxr[maxn],ans,frontx;
int n,m,a[maxn],opt,le;
int ri,v,sum[maxn];

inline void pushup(int o,int lc,int rc){
	sum[o]=sum[lc]+sum[rc];
	mx[o]=max(mx[lc],max(mx[rc],mxl[rc]+mxr[lc]));
	mxl[o]=max(mxl[lc],sum[lc]+mxl[rc]);
	mxr[o]=max(mxr[rc],sum[rc]+mxr[lc]);
}

void build(int o,int l,int r){
	if(l==r){
		mxl[o]=mx[o]=mxr[o]=sum[o]=a[l];
		return;
	}
	
	int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
	build(lc,l,mid),build(rc,mid+1,r);
	pushup(o,lc,rc);
}

void update(int o,int l,int r){
	if(l==r){
		mxl[o]=mx[o]=mxr[o]=sum[o]=v;
		return;
	}
	
	int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
	if(le<=mid) update(lc,l,mid);
	else update(rc,mid+1,r);
	pushup(o,lc,rc);
}

void query(int o,int l,int r){
	if(l>=le&&r<=ri){
		ans=max(ans,max(frontx+mxl[o],mx[o]));
		frontx=max(frontx+sum[o],mxr[o]);
		return;
	}
	
	int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
	if(le<=mid) query(lc,l,mid);
	if(ri>mid) query(rc,mid+1,r);
}

inline void req(){
	ans=-inf,frontx=0;
	query(1,1,n);
	printf("%d\n",ans);
} 

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",a+i);
	build(1,1,n);
	scanf("%d",&m);
	while(m--){
		scanf("%d%d%d",&opt,&le,&ri);
		if(opt) req();
		else{
			v=ri;
			update(1,1,n);
		}
	}
	
	return 0;
}

  


posted @ 2018-02-21 14:48  蒟蒻JHY  阅读(452)  评论(0编辑  收藏  举报