SPOJ GSS5 Can you answer these queries V(区间合并)

Can you answer these queries V

Description

You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| <= 10000 , 1 <= N <= 10000 ). A query is defined as follows: Query(x1,y1,x2,y2) = Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 <= j <= y2 and x1 <= x2 , y1 <= y2 }. Given M queries (1 <= M <= 10000), your program must output the results of these queries.

Input

The first line of the input consist of the number of tests cases <= 5. Each case consist of the integer N and the sequence A. Then the integer M. M lines follow, contains 4 numbers x1, y1, x2 y2.

Output

Your program should output the results of the M queries for each test case, one query per line.

Example

Input:
2
6 3 -2 1 -4 5 2
2
1 1 2 3
1 3 2 5
1 1
1
1 1 1 1

Output:
2
3
1


Hint

Added by:Frank Rafael Arteaga
Date:2008-08-06
Time limit:0.132s
Source limit:50000B
Memory limit:1536MB
Cluster:Cube (Intel G860)
Languages:All except: C99 strict ERL JS NODEJS PERL 6 VB.net
Resource:K.-Y. Chen and K.-M. Chao, On the Range Maximum-Sum Segment Query Problem, 2007.

解题思路:

分为三种情况.

1. x1 y1 x2 y2  

这种情况就是   x1 y1 的右最大  +   sum【y1  x2】 + x2 y2的做最大

2.x1 x2 y2 y1 其实就是 y1==y2的时候

要么区间在 x2-y2之间

要么区间的头在  x1 x2之间,尾在 x2 y2之间

3. x1 x2 y1 y2。

这种情况和2比较像是  这个时候  x1-y2 区间分成三段。只需要枚举头尾各在区间哪个区间就好了。

需要注意的是:有可能 x2==y1。

所以要注意一下比较的时候的边界。

AC代码:

#include <iostream>
#include <cstdio>
#define lson id<<1,s,mid
#define rson id<<1|1,mid+1,e
using namespace std;

const int N = 10005;
int tree[N<<2];
int lef[N<<2];
int rig[N<<2];
int sum[N<<2];

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

int Q_sum(int id,int s,int e,int l,int r){
    if(l > r)
        return 0;
    if(l<=s && r>=e){
        return sum[id];
    }
    int mid = (s+e)>>1;
    if(r <= mid)
        return Q_sum(lson,l,r);
    else if(l>mid)
        return Q_sum(rson,l,r);
    else{
        return Q_sum(lson,l,mid)+Q_sum(rson,mid+1,r);
    }
}

int Q_L(int id,int s,int e,int l,int r){
    if(l > r)
        return 0;
    if(l<=s && r>=e){
        return lef[id];
    }
    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(Q_L(lson,l,mid),max(Q_sum(lson,l,mid),Q_sum(lson,l,mid)+Q_L(rson,mid+1,r)));
}

int Q_R(int id,int s,int e,int l,int r){
    if(l > r)
        return 0;
    if(l<=s && r>=e){
        return rig[id];
    }
    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(Q_R(rson,mid+1,r),max(Q_sum(rson,mid+1,r),Q_sum(rson,mid+1,r)+Q_R(lson,l,mid)));
}

int query(int id,int s,int e,int l,int r){
    if(l > r)
        return 0;
    if(l<=s && r>=e){
        return tree[id];
    }
    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_L(rson,mid+1,r)+Q_R(lson,l,mid),max(query(lson,l,mid),query(rson,mid+1,r)));
    }
}


int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        build(1,1,n);
        int m;
        scanf("%d",&m);
        while(m--){
            int x1,x2,y1,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            if(x2 > y1){
                printf("%d\n",Q_R(1,1,n,x1,y1)+Q_sum(1,1,n,y1+1,x2-1)+Q_L(1,1,n,x2,y2));
            }else if(y1 == y2){
                printf("%d\n",max(query(1,1,n,x2,y2),Q_L(1,1,n,x2,y2)+Q_R(1,1,n,x1,x2-1)));
            }else{
                printf("%d\n",max(Q_R(1,1,n,x1,x2-1)+Q_L(1,1,n,x2,y1),max(Q_R(1,1,n,x1,x2-1)+Q_L(1,1,n,y1+1,y2)+Q_sum(1,1,n,x2,y1),max(Q_R(1,1,n,x2,y1)+Q_L(1,1,n,y1+1,y2),query(1,1,n,x2,y1)))));
            }
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洛谷的SPOJ需要注册一个SPOJ账号并进行绑定才能进行交题。您可以按照以下步骤进行注册: 1. 打开洛谷网站(https://www.luogu.com.cn/)并登录您的洛谷账号。 2. 在网站顶部导航栏中找到“题库”选项,将鼠标悬停在上面,然后选择“SPOJ”。 3. 在SPOJ页面上,您会看到一个提示,要求您注册SPOJ账号并进行绑定。点击提示中的链接,将会跳转到SPOJ注册页面。 4. 在SPOJ注册页面上,按照要求填写您的用户名、密码和邮箱等信息,并完成注册。 5. 注册完成后,返回洛谷网站,再次进入SPOJ页面。您会看到一个输入框,要求您输入刚刚注册的SPOJ用户名。输入用户名后,点击“绑定”按钮即可完成绑定。 现在您已经成功注册并绑定了SPOJ账号,可以开始在洛谷的SPOJ题库上刷题了。祝您顺利完成编程练习!\[1\]\[2\] #### 引用[.reference_title] - *1* *3* [(洛谷入门系列,适合洛谷新用户)洛谷功能全解](https://blog.csdn.net/rrc12345/article/details/122500057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [luogu p7492 序列](https://blog.csdn.net/zhu_yin233/article/details/122051384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值