SPOJ GSS3 Can you answer these queries III(线段树)

来源:互联网 发布:zanti软件扫描不到 编辑:程序博客网 时间:2024/05/16 17:25

Can you answer these queries III

Description

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 }.

Input

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 }.

Output

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

Example

Input:41 2 3 441 1 30 3 -31 2 41 3 3Output:64-3

解题思路:

在询问一段数列的连续最大自序列和的基础上,增加了单点修改。

AC代码:

#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int N = 50005;int a[N];struct node{    int l,r,lx,rx,mx,sum;}tree[N<<2];void pushUp(int id){    tree[id].lx = max(tree[id<<1].lx,tree[id<<1|1].lx+tree[id<<1].sum);    tree[id].rx = max(tree[id<<1|1].rx,tree[id<<1].rx+tree[id<<1|1].sum);    tree[id].mx = max(max(tree[id<<1].mx,tree[id<<1|1].mx),tree[id<<1].rx+tree[id<<1|1].lx);    tree[id].sum = tree[id<<1].sum+tree[id<<1|1].sum;}void build(int id,int l,int r){    tree[id].l = l;    tree[id].r = r;    if(l == r){        tree[id].lx = tree[id].rx = tree[id].mx = tree[id].sum = a[l];        return ;    }    int mid = (l+r)/2;    build(id<<1,l,mid);    build(id<<1|1,mid+1,r);    pushUp(id);}int Q_L(int id,int l,int r){    if(tree[id].l == l && tree[id].r == r)        return tree[id].lx;    int mid = (tree[id].l+tree[id].r)/2;    if(r <= mid)        return Q_L(id<<1,l,r);    else if(l > mid)        return Q_L(id<<1|1,l,r);    else return max(Q_L(id<<1,l,mid),max(tree[id<<1].sum,tree[id<<1].sum+Q_L(id<<1|1,mid+1,r)));}int Q_R(int id,int l,int r){    if(tree[id].l == l && tree[id].r == r)        return tree[id].rx;    int mid = (tree[id].l+tree[id].r)/2;    if(r <= mid)        return Q_R(id<<1,l,r);    else if(l > mid)        return Q_R(id<<1|1,l,r);    else return max(Q_R(id<<1|1,mid+1,r),max(tree[id<<1|1].sum,tree[id<<1|1].sum+Q_R(id<<1,l,mid)));}void update(int id,int x,int val){    if(tree[id].l == tree[id].r){        tree[id].mx += val;        tree[id].rx += val;        tree[id].lx += val;        tree[id].sum += val;        return ;    }    int mid = (tree[id].l+tree[id].r)/2;    if(x <= mid)        update(id<<1,x,val);    else        update(id<<1|1,x,val);    pushUp(id);}int query(int id,int l,int r){    if(tree[id].l == l && tree[id].r == r)        return tree[id].mx;    int mid = (tree[id].l+tree[id].r)/2;    if(r <= mid)        return query(id<<1,l,r);    else if(l > mid)        return query(id<<1|1,l,r);    else return max(max(query(id<<1,l,mid),query(id<<1|1,mid+1,r)),Q_R(id<<1,l,mid)+Q_L(id<<1|1,mid+1,r));}int main(){    int n,m;    while(~scanf("%d",&n)){        for(int i = 1; i <= n; i++)            scanf("%d",&a[i]);        build(1,1,n);        int op,x,y;        scanf("%d",&m);        while(m--){            scanf("%d%d%d",&op,&x,&y);            if(op == 0){                update(1,x,y-a[x]);                a[x] = y;            }            else                printf("%d\n",query(1,x,y));        }    }    return 0;}


0 0