SPOJ GSS5 Can you answer these queries V
| Time Limit: 132MS | Memory Limit: 1572864KB | 64bit IO Format: %lld & %llu | 
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. | 
又是查询最大连续字段和,但是限制了左右端点所在的区间……
线段树的部分不需要改动,计算答案的时候改一下即可。
如果区间有重复部分,就把区间分成三段,左段里找左端点,右段里找右端点,然后并上中段。有一串麻烦的判断,具体看代码。
如果区间没有重复部分,就左段里找左端点,右段里找右端点,然后强制加上两区间中间的序列和。
/*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m;
int data[mxn];
struct node{
int mx;
int ml,mr;
int smm;
}t[mxn<<],tmp0;
void Build(int l,int r,int rt){
if(l==r){t[rt].mx=t[rt].ml=t[rt].mr=data[l];t[rt].smm=data[l];return;}
int mid=(l+r)>>;
Build(l,mid,lc);
Build(mid+,r,rc);
t[rt].smm=t[lc].smm+t[rc].smm;
t[rt].mx=max(t[lc].mx,t[rc].mx);
t[rt].mx=max(t[lc].mr+t[rc].ml,t[rt].mx);
t[rt].ml=max(t[lc].ml,t[lc].smm+t[rc].ml);
t[rt].mr=max(t[rc].mr,t[rc].smm+t[lc].mr);
return;
}
node query(int L,int R,int l,int r,int rt){
// printf("%d %d %d %d %d\n",L,R,l,r,rt);
if(R<L){
return (node){,,,};
}
if(L<=l && r<=R){return t[rt];}
int mid=(l+r)>>;
node res1;
if(L<=mid)res1=query(L,R,l,mid,lc);
else res1=tmp0;
node res2;
if(R>mid)res2=query(L,R,mid+,r,rc);
else res2=tmp0;
node res={};
res.smm=res1.smm+res2.smm;
res.mx=max(res1.mx,res2.mx);
res.mx=max(res.mx,res1.mr+res2.ml);
res.ml=max(res1.ml,res1.smm+res2.ml);
res.mr=max(res2.mr,res2.smm+res1.mr);
return res;
}
int qsum(int L,int R,int l,int r,int rt){
if(L<=l && r<=R)return t[rt].smm;
int mid=(l+r)>>;
int res=;
if(L<=mid)res+=qsum(L,R,l,mid,lc);
if(R>mid)res+=qsum(L,R,mid+,r,rc);
return res;
}
int main(){
int T;
T=read();
while(T--){
n=read();
int i,j,x0,y0,x2,y2;
for(i=;i<=n;i++)data[i]=read();
Build(,n,);
m=read();
tmp0.ml=tmp0.mr=tmp0.mx=-1e9;tmp0.smm=;
for(i=;i<=m;i++){
x0=read();y0=read();x2=read();y2=read();
int tmp=;
int ans=-1e9;
if(y0>=x2){
//区间重叠
node res=query(x2,y0,,n,);
node res1=query(x0,x2-,,n,);
node res2=query(y0+,y2,,n,);
ans=max(ans,res1.mr+res.smm+res2.ml);
ans=max(ans,res1.mr+res.ml);
ans=max(ans,res.mr+res2.ml);
ans=max(ans,res.mx);
}
else{
//区间未重叠
if(y0+<x2)tmp=qsum(y0+,x2-,,n,);
node res1=query(x0,y0,,n,);
node res2=query(x2,y2,,n,);
ans=max(ans,tmp+res1.mr+res2.ml);
}
//printf("%d\n",query(x2,y2,1,n,1).mx);
printf("%d\n",ans);
}
}
return ;
}
SPOJ GSS5 Can you answer these queries V的更多相关文章
- SPOJ GSS5 Can you answer these queries V ——线段树
		[题目分析] GSS1上增加区间左右端点的限制. 直接分类讨论就好了. [代码] #include <cstdio> #include <cstring> #include & ... 
- GSS5 spoj 2916. Can you answer these queries V 线段树
		gss5 Can you answer these queries V 给出数列a1...an,询问时给出: Query(x1,y1,x2,y2) = Max { A[i]+A[i+1]+...+A[ ... 
- SPOJ 2916 GSS5 - Can you answer these queries V
		传送门 解题思路 和GSS1相似,但需要巨恶心的分类讨论,对于x1<=y1< x2< =y2 这种情况 , 最大值应该取[x1,y1]的右端最大+[y1+1,x2-1]的和+[x2, ... 
- SPOJ 2916 Can you answer these queries V(线段树-分类讨论)
		题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出一个数列.每次查询最大子段和Sum[i,j],其中i和j满足x1<=i<=y1,x2<=j& ... 
- [GSS5] Can you answer these queries V
		大力讨论. luogu上交spoj的题卡的一比... 难受 wa了好几次,原因大概首先求的是非空区间,不能乱和0取max,第二点是求无相交的解时,在两段求lmx和rmx的时候可以取max(0). 区间 ... 
- SP2916 GSS5 - Can you answer these queries V
		给定一个序列.查询左端点在$[x_1, y_1]$之间,且右端点在$[x_2, y_2]$之间的最大子段和,数据保证$x_1\leq x_2,y_1\leq y_2$,但是不保证端点所在的区间不重合 ... 
- 题解 SP2916 【GSS5 - Can you answer these queries V】
		前言 最近沉迷于数据结构,感觉数据结构很有意思. 正文 分析 先来分类讨论一下 1. \(x2<y1\) 如果 \(y1<x2\) 的话,答案 \(=\max \limits_{ y1 \ ... 
- SPOJ GSS3 Can you answer these queries III[线段树]
		SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ... 
- GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树
		GSS7Can you answer these queries VII 给出一棵树,树的节点有权值,有两种操作: 1.询问节点x,y的路径上最大子段和,可以为空 2.把节点x,y的路径上所有节点的权 ... 
随机推荐
- 扩展 easyui-tabs 插件 关闭标签页方法
			$.extend($.fn.tabs.methods,{ allTabs:function(jq){ var tabs = $(jq).tabs('tabs'); var all = []; all ... 
- [MetaHook] Quake FMOD player demo
			CFMOD.h #ifndef CFMOD_H #define CFMOD_H #include "qfmod.h" struct Sound_t { char *pszName; ... 
- 数据字典生成工具之旅(8):SQL查询表的约束默认值等信息
			上一篇代码生成工具里面已经用到了读取表结构的SQL,这篇将更加详细的介绍SQL SERVER常用的几张系统表和视图! 阅读目录 系统表视图介绍 实际应用 本章总结 工具源代码下载 学习使用 回到顶部 ... 
- 发布我的图片预加载控件YPreLoadImg v1.0
			介绍 大家好!很高兴向大家介绍我的图片预加载控件YPreLoadImg.它可以帮助您预加载图片,并且能显示加载的进度,在预加载完成后调用指定的方法. YPreLoadImg控件由一个名为PreLoad ... 
- requirejs:性能优化-及早并行加载
			为了提高页面的性能,通常情况下,我们希望资源尽可能地早地并行加载.这里有两个要点,首先是尽早,其次是并行. 通过data-main方式加载要尽可能地避免,因为它让requirejs.业务代码不必要地串 ... 
- 搭建emacs的go编程语言环境
			关于emacs就不说明了,直接切入主题.关于我的emacs配置,可以直接参考GitHub上的lienhua34/myemacs-conf. go-mode 安装 关于go-mode的安装,可以直接参考 ... 
- Bootstrap系列 -- 1. 如何使用Bootstrap
			一. Bootstrap 简介 Bootstrap 是一个前端框架,使用Bootstrap可以做出很多漂亮的页面,中文官网:http://www.bootcss.com/ 二. Bootstrap核心 ... 
- 项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享
			因业务发展需要现在的系统不足以支撑现在的用户量,于是我们在一周之前着手项目的性能优化与分布式部署的相关动作. 概况 现在的系统是基于RabbitHub(一套开源的开发时框架)和Rabbit.WeiXi ... 
- IE对象最后一个属性后不要加逗号,否则在IE7及以下版本中会报错
			某函数返回一个对象,如果在最后一个属性后加逗号,IE7及以下版本中会报错 正确代码: return{ top:rect.top-top, bottom:rect.bottom-top, left:re ... 
- 2-ls 显示目录内容
			ls list directory contents 显示目录内容 [语法]: ls [选项] [参数] [功能介绍] ls指令用来显示目录列表,在Linux系统中有着较高的使用率.ls指令的输出信息 ... 
