SPOJ 1043 1043. Can you answer these queries I

思路:用TREE记录节点的最大连续和,LEF记录左边开始的最大连续和,RIG记右边开始的最大连续和

然后处理的时候就是比较左边最大,右边最大  中间区间的问题

其中这个query 只能膜拜了。。。

大大缩减了时间。放弃治疗的我只会用三个函数

传参就要传出翔。

flag == -1表示要左边最大

flag == 1 表示要右边最大

然后ans在找到的区间的同时进行比较。

我已可入灵魂

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#define MAXN 50005
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e

using namespace std;

int tree[MAXN<<2];
int lef[MAXN<<2];
int rig[MAXN<<2];
int X[MAXN]={0};
int n;
int cnt;

inline void pushup(int num,int s,int e)
{
    int mid=(s+e)>>1;

    lef[num]=max(lef[num<<1],X[mid]-X[s-1]+lef[num<<1|1]);
    rig[num]=max(rig[num<<1|1],X[e]-X[mid]+rig[num<<1]);
    tree[num]=max(lef[num<<1|1]+rig[num<<1],max(tree[num<<1],tree[num<<1|1]));
}


void build(int num,int s,int e)
{
    if(s==e)
    {
        scanf("%d",&tree[num]);
        lef[num]=rig[num]=tree[num];
        X[cnt]=X[cnt-1]+tree[num];
        cnt++;
        return;
    }
    int mid=(s+e)>>1;

    build(num<<1,s,mid);
    build(num<<1|1,mid+1,e);
    pushup(num,s,e);
}

int query(int num, int s, int e, int l, int r, int flag, int &ans)
{
    int mid = (s+e)>>1;
    if(s >= l && e <= r)
    {
        ans = max(ans, tree[num]);
        return flag == -1 ? lef[num] : rig[num];
    }
    if(mid >= r)
        return query(num<<1, s, mid, l, r, -1, ans);
    else if(mid  < l)
        return query(num<<1|1, mid + 1, e, l, r, 1, ans);
    else
    {
        int ln, rn;
        ln = query(num<<1, s, mid, l, r, 1, ans);
        rn = query(num<<1|1, mid + 1, e, l, r, -1, ans);
        ans = max(ans, ln + rn);
        if(flag == -1)
            return max(lef[num<<1], X[mid] - X[s - 1] + rn);
        else
            return max(rig[num<<1|1], X[e] - X[mid] + ln);
    }
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        cnt=1;
        X[0]=0;
        build(1,1,n);

        int m;
        scanf("%d",&m);
        while(m--)
        {
            int aa,bb;
            scanf("%d%d",&aa,&bb);
            int ans=X[aa]-X[aa-1];
            query(1,1,n,aa,bb,-1,ans);
            printf("%d\n",ans);
        }
    }
    return 0;
}

/*
8
-1 5 -6 7 -4 8 -2 7
999
*/


 

 

posted @ 2013-08-13 19:38  pangbangb  阅读(231)  评论(0编辑  收藏  举报