spoj 1716 Can you answer these queries III

来源:互联网 发布:雅思在线模拟考试软件 编辑:程序博客网 时间:2024/06/10 21:33

和上回做的线段树几乎一样。

http://blog.csdn.net/johsnows/article/details/62237377

不过这回只能有单点更新的方法去做了


代码:

#include <bits/stdc++.h>#define LL long long using namespace std;const int maxn=5e4+5;const int inf=10000;struct p{    LL lmax;    LL rmax;    LL max;    LL sum;    void init()    {        sum=0;        lmax=rmax=max=-inf;        return;    }    void maintan(p a, p b)    {        sum=a.sum+b.sum;        lmax=a.lmax>(a.sum+b.lmax)?a.lmax:(a.sum+b.lmax);        rmax=b.rmax>(b.sum+a.rmax)?b.rmax:(b.sum+a.rmax);        max=a.max>b.max?a.max:b.max;        max=max>(a.rmax+b.lmax)?max:(a.rmax+b.lmax);        return;    }}seg[maxn<<4];void update (int e, int l, int r, int ll, int x){ //   printf("%d %d\n", l, r);    if(l==r && r==ll)    {        seg[e].sum=seg[e].max=seg[e].lmax=seg[e].rmax=x;//        printf("update%d %d %lld\n", l, r, seg[e].max);        return;     }    int mid=(l+r)/2;    if(ll<=mid)update(e<<1, l, mid, ll, x);    else update(e<<1|1, mid+1, r, ll, x);    seg[e].maintan(seg[e<<1], seg[e<<1|1]);     return;}p query(int e, int l, int r, int ll, int rr){ //   printf("%d %d\n", l, r);    p res;    res.init();    if(ll<=l && r<=rr)    {        return seg[e];           }    int mid=(l+r)/2;    if(ll<=mid)res.maintan(query(e<<1, l, mid, ll, rr), res);//    printf("a %d %d %lld\n", l, r, res.max);    if(rr>mid)res.maintan(res, query(e<<1|1, mid+1, r, ll, rr));//    printf("b %d %d %lld\n", l, r, res.max);    return res;}int main(){    int n;    cin>>n;    int i, j, x;    for(i=1; i<=n; i++)    {        scanf("%d", &x);        update(1, 1, n, i, x);            }//    for(i=1; i<=n; i++)printf("%lld\n", seg[i].max);    int m,y,z;    cin>>m;    for(i=0; i<m; i++)    {        scanf("%d%d%d", &x, &y, &z);        if(x==0)        {            update(1, 1, n, y, z);        }        else         {            p ans;            ans=query(1, 1, n, y, z);            printf("%lld\n", ans.max);        }    }   }


0 0