首页 > 代码库 > SPOJ GSS3 Can you answer these queries III (线段树)

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

题目大意:

求区间最大子区间的和。


思路分析:

记录左最大,右最大,区间最大。


注意Q_L  和 Q_R  就好。



#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#define maxn 55555
using namespace std;

int lef[maxn<<2];
int rig[maxn<<2];
int tre[maxn<<2];
int sum[maxn<<2];

void pushup(int num)
{
    sum[num]=sum[num<<1]+sum[num<<1|1];

    lef[num]=max(lef[num<<1],sum[num<<1]+lef[num<<1|1]);
    rig[num]=max(rig[num<<1|1],sum[num<<1|1]+rig[num<<1]);
    tre[num]=max(max(tre[num<<1],tre[num<<1|1]),rig[num<<1]+lef[num<<1|1]);
}
void build(int num,int s,int e)
{
    if(s==e)
    {
        scanf("%d",&tre[num]);
        sum[num]=rig[num]=lef[num]=tre[num];
        return ;
    }
    int mid=(s+e)>>1;

    build(lson);
    build(rson);

    pushup(num);
}
int Q_L(int num,int s,int e,int l,int r)
{
    if(l<=s && r>=e)
    {
        return lef[num];
    }
    int mid=(s+e)>>1;

    if(r<=mid)return Q_L(lson,l,r);
    else if(l>mid)return Q_L(rson,l,r);
    else
    {
        return max(lef[num<<1],max(sum[num<<1],sum[num<<1]+Q_L(rson,mid+1,r)));
    }
}
int Q_R(int num,int s,int e,int l,int r)
{
    if(l<=s && r>=e)
    {
        return rig[num];
    }
    int mid=(s+e)>>1;

    if(r<=mid)return Q_R(lson,l,r);
    else if(l>mid)return Q_R(rson,l,r);
    else
    {
        return max(rig[num<<1|1],max(sum[num<<1|1],sum[num<<1|1]+Q_R(lson,l,mid)));
    }
}
int query(int num,int s,int e,int l,int r)
{
    if(l<=s && r>=e)
    {
        return tre[num];
    }

    int mid=(s+e)>>1;

    if(r<=mid)return query(lson,l,r);
    else if(l>mid)return query(rson,l,r);
    else
    {
        return max(Q_R(lson,l,mid)+Q_L(rson,mid+1,r),max(query(lson,l,mid),query(rson,mid+1,r)));
    }
}
void update(int num,int s,int e,int pos,int val)
{
    if(s==e)
    {
        sum[num]=tre[num]=lef[num]=rig[num]=val;
        return;
    }
    int mid=(s+e)>>1;

    if(pos<=mid)update(lson,pos,val);
    else update(rson,pos,val);

    pushup(num);
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        build(1,1,n);
        int m;
        scanf("%d",&m);
        while(m--)
        {
            int op,l,r;
            scanf("%d%d%d",&op,&l,&r);

            if(op)
            printf("%d\n",query(1,1,n,l,r));
            else update(1,1,n,l,r);
        }
    }
    return 0;
}