Can you answer these queries III
http://www.spoj.pl/problems/GSS3/
题意:求区间的最大连续序列和,带修改。
思路:和GSS1差不多,多一个更新而已。

#include<stdio.h> #include<string.h> #include<iostream> #define lson rt<<1 #define rson rt<<1|1 #define LL long long using namespace std; const LL maxn = 50005; LL bs[maxn],n,m; struct nd{ LL lx,rx,mx,sum; }as[maxn*4]; inline void pushUp(LL rt) { as[rt].lx = max(as[lson].lx,max(as[lson].sum,as[lson].sum+as[rson].lx)); as[rt].rx = max(as[rson].rx,max(as[rson].sum,as[rson].sum+as[lson].rx)); as[rt].mx = max(max(as[rson].mx,as[lson].mx),as[lson].rx+as[rson].lx); as[rt].sum = as[lson].sum + as[rson].sum; } void build(LL rt,LL l,LL r) { LL md = (l + r) >> 1; if(l==r){ as[rt].lx=as[rt].rx=as[rt].sum=as[rt].mx=bs[l]; bs[l]=rt; return; } build(lson,l,md); build(rson,md+1,r); pushUp(rt); } LL queryL(LL rt,LL l,LL r,LL L,LL R) { LL md = (l + r) >> 1; if(l==L&&r==R)return as[rt].lx; if(R<=md)return queryL(lson,l,md,L,R); if(L>md)return queryL(rson,md+1,r,L,R); return max(queryL(lson,l,md,L,md),max(as[lson].sum,as[lson].sum+queryL(rson,md+1,r,md+1,R))); } LL queryR(LL rt,LL l,LL r,LL L,LL R) { LL md = (l + r) >> 1; if(l==L&&r==R)return as[rt].rx; if(R<=md)return queryR(lson,l,md,L,R); if(L>md)return queryR(rson,md+1,r,L,R); return max(queryR(rson,md+1,r,md+1,R),max(as[rson].sum,as[rson].sum+queryR(lson,l,md,L,md))); } LL query(LL rt,LL l,LL r,LL L,LL R) { LL md = (l + r) >> 1; if(l==L&&r==R) return as[rt].mx; if(R<=md)return query(lson,l,md,L,R); if(L>md)return query(rson,md+1,r,L,R); return max(max(query(lson,l,md,L,md),query(rson,md+1,r,md+1,R)),queryR(lson,l,md,L,md)+queryL(rson,md+1,r,md+1,R)); } inline void update(LL rt,LL v) { rt = bs[rt]; as[rt].rx = as[rt].sum = as[rt].mx = as[rt].lx = v; rt /= 2; while(rt){ pushUp(rt); rt /= 2; } } int main() { while(scanf("%lld",&n)==1){ for(LL i = 1; i <= n; ++ i) scanf("%lld",bs+i); build(1,1,n); scanf("%lld",&m); while(m--){ LL o,l,r; scanf("%lld %lld %lld",&o,&l,&r); if(o)printf("%lld\n",query(1,1,n,l,r)); else update(l,r); } } return 0; }