线段树 SP1716 GSS3 - Can you answer these queries III

SP1716 GSS3 - Can you answer these queries III

题意翻译

n 个数,q 次操作

操作0 x y把A_xAx 修改为yy

操作1 l r询问区间[l, r] 的最大子段和

依旧是维护最大子段和,还是再敲一遍比较好。

code:

#include<iostream>
#include<cstdio>
#define ls(o) o<<1
#define rs(o) o<<1|1
using namespace std;
const int wx=100017;
inline int read(){
	int sum=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0';ch=getchar();}
	return sum*f;
}
struct val_tree{
	int l,r,lsum,rsum,sum,tot;
	#define sum(o) t[o].sum
	#define lsum(o) t[o].lsum
	#define rsum(o) t[o].rsum
	#define tot(o) t[o].tot
}t[wx*4];
int a[wx];
int n,m;
void up(int o){
	tot(o)=tot(ls(o))+tot(rs(o));
	lsum(o)=max(lsum(ls(o)),tot(ls(o))+lsum(rs(o)));
	rsum(o)=max(rsum(rs(o)),tot(rs(o))+rsum(ls(o)));
	sum(o)=max(rsum(ls(o))+lsum(rs(o)),max(sum(ls(o)),sum(rs(o))));
}
void build(int o,int l,int r){
	t[o].l=l;t[o].r=r;
	if(l==r){sum(o)=lsum(o)=rsum(o)=tot(o)=a[l];return ;}
	int mid=t[o].l+t[o].r>>1;
	if(l<=mid)build(ls(o),l,mid);
	if(r>mid)build(rs(o),mid+1,r);
	up(o);
}
void update(int o,int l,int r,int k){
	if(l<=t[o].l&&t[o].r<=r){
		sum(o)=lsum(o)=rsum(o)=tot(o)=k;
		return ;
	}
	int mid=t[o].l+t[o].r>>1;
	if(l<=mid)update(ls(o),l,r,k);
	if(r>mid)update(rs(o),l,r,k);
	up(o);
}
val_tree query(int o,int l,int r){
	if(l<=t[o].l&&t[o].r<=r){
		return t[o];
	}
	int mid=t[o].l+t[o].r>>1;
	if(r<=mid)return query(ls(o),l,r);
	if(l>mid)return query(rs(o),l,r);
	val_tree tmp,tmp1,tmp2;
	tmp1=query(ls(o),l,r);
	tmp2=query(rs(o),l,r);
	tmp.tot=tmp1.tot+tmp2.tot;
	tmp.lsum=max(tmp1.lsum,tmp1.tot+tmp2.lsum);
	tmp.rsum=max(tmp2.rsum,tmp2.tot+tmp1.rsum);
	tmp.sum=max(tmp1.rsum+tmp2.lsum,max(tmp1.sum,tmp2.sum));
	return tmp;
}
int main(){
	n=read();
	for(int i=1;i<=n;i++)a[i]=read();
	build(1,1,n);
	m=read();
	for(int i=1,x,y,opt;i<=m;i++){
		opt=read();x=read();y=read();
		if(opt)printf("%d\n",query(1,x,y).sum);
		else update(1,x,x,y);
	}
	return 0;
}
posted @ 2018-10-14 16:55  _王小呆  阅读(239)  评论(0编辑  收藏  举报