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$,但是不保证端点所在的区间不重合
这题可以分为几种情况讨论
$y_1<x_2$
那么这个时候发现$[y_1+1,x_2-1]$里的数必须得选,并选出$[x1,y1]$的最大后缀和$[x2,y2]$的最大前缀。用结构体维护一下就好了
$y_1\geq x_2$
发现这个时候左右端点所在区间的情况分别如下
$l$在$[x_1,x_2]$,$r$在$[x_2,y_1]$,那么只要查询$[x_1,x_2]$的最大后缀和$[x_2,y_1]$的最大前缀
$l$在$[x_1,x_2]$,$r$在$[y_1,y_2]$,那么只要查询$[x_1,x_2]$的最大后缀和$[x_2,y_2]$的最大前缀
$l$在$[x_2,y_1]$,$r$在$[x_2,y_1]$,那么只要查询$[x_2,y_1]$的最大子段和
$l$在$[x_2,y_1]$,$r$在$[y_1,y_2]$,那么只要查询$[x_2,y_1]$的最大后缀和$[y_1,y_2]$的最大前缀
//minamoto
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ls (p<<1)
#define rs (p<<1|1)
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=1e4+;int a[N],n,m;
struct node{int pre,mid,suf,sum;}b[N<<];
node merge(node l,node r){
node ans;
ans.pre=max(l.pre,l.sum+r.pre);
ans.mid=max(max(l.mid,r.mid),l.suf+r.pre);
ans.suf=max(l.suf+r.sum,r.suf);
ans.sum=l.sum+r.sum;
return ans;
}
void upd(int p){b[p]=merge(b[ls],b[rs]);}
void build(int p,int l,int r){
if(l==r) return (void)(b[p].pre=b[p].mid=b[p].suf=b[p].sum=a[l]);
int mid=(l+r)>>;
build(ls,l,mid),build(rs,mid+,r);
upd(p);
}
node query(int p,int l,int r,int ql,int qr){
if(ql>qr) return (node){,,,};
if(ql<=l&&qr>=r) return b[p];
int mid=(l+r)>>;
if(qr<=mid) return query(ls,l,mid,ql,qr);
else if(ql>mid) return query(rs,mid+,r,ql,qr);
else return merge(query(ls,l,mid,ql,qr),query(rs,mid+,r,ql,qr));
}
int get(int l1,int r1,int l2,int r2){
if(r1<l2){
int tmp=query(,,n,l1,r1).suf;
tmp+=query(,,n,r1+,l2-).sum;
tmp+=query(,,n,l2,r2).pre;
return tmp;
}
int ans=query(,,n,l2,r1).mid;
if(l1<l2) cmax(ans,query(,,n,l1,l2).suf+query(,,n,l2,r2).pre-a[l2]);
if(r2>r1) cmax(ans,query(,,n,l1,r1).suf+query(,,n,r1,r2).pre-a[r1]);
return ans;
}
int main(){
// freopen("testdata.in","r",stdin);
int T=read();
while(T--){
n=read();
for(int i=;i<=n;++i) a[i]=read();
build(,,n);
m=read();
while(m--){
int l1=read(),r1=read(),l2=read(),r2=read();
print(get(l1,r1,l2,r2));
}
}
return Ot(),;
}
SP2916 GSS5 - Can you answer these queries V的更多相关文章
- 题解 SP2916 【GSS5 - Can you answer these queries V】
前言 最近沉迷于数据结构,感觉数据结构很有意思. 正文 分析 先来分类讨论一下 1. \(x2<y1\) 如果 \(y1<x2\) 的话,答案 \(=\max \limits_{ y1 \ ...
- SPOJ GSS5 Can you answer these queries V
Time Limit: 132MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Description You are g ...
- 【SP2916】Can you answer these queries V - 线段树
题面 You are given a sequence \(a_1,a_2,...,a_n\). (\(|A[i]| \leq 10000 , 1 \leq N \leq 10000\)). A qu ...
- SPOJ GSS5 Can you answer these queries V ——线段树
[题目分析] GSS1上增加区间左右端点的限制. 直接分类讨论就好了. [代码] #include <cstdio> #include <cstring> #include & ...
- [GSS5] Can you answer these queries V
大力讨论. luogu上交spoj的题卡的一比... 难受 wa了好几次,原因大概首先求的是非空区间,不能乱和0取max,第二点是求无相交的解时,在两段求lmx和rmx的时候可以取max(0). 区间 ...
- SPOJ 2916 GSS5 - Can you answer these queries V
传送门 解题思路 和GSS1相似,但需要巨恶心的分类讨论,对于x1<=y1< x2< =y2 这种情况 , 最大值应该取[x1,y1]的右端最大+[y1+1,x2-1]的和+[x2, ...
- 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[ ...
- Can you answer these queries V SPOJ - GSS5 (分类讨论+线段树维护区间最大子段和)
recursion有一个整数序列a[n].现在recursion有m次询问,每次她想知道Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 &l ...
- SPOJ 2916 Can you answer these queries V(线段树-分类讨论)
题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出一个数列.每次查询最大子段和Sum[i,j],其中i和j满足x1<=i<=y1,x2<=j& ...
随机推荐
- Leetcode 143.重排链表
重排链表 给定一个单链表 L:L0→L1→…→Ln-1→Ln ,将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→… 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 示 ...
- hihoCoder#1054 滑动解锁
原题地址 回溯搜索 对于每个待枚举的点,检查: 1. 度数检查:是否违反了出度入度限制.因为生成的路径除了首尾节点外,其他节点的出度和入度只能为2 2. 共线检查:是否违反了共线条件.即跨越了尚未枚举 ...
- bzoj 1962 硬币游戏 (猜数问题)
[bzoj1962]模型王子 2015年3月26日1,6460 Description Input 输入数据共一行,两个整数N,K,用一个空格隔开,具体意义如题目中所述. Output 输出数据共一行 ...
- 2018/3/3 解析ThreadLocal源码
今天听到一个老哥说道ThreadLocal在源码设计上面的一些好处,于是决定把ThreadLocal源码彻底分析一下. 首先,我们来看下set方法 可以看到,这个方法里,先获得了当前线程,之后将当前线 ...
- Linux系统备份还原工具2(TAR/压缩工具)
相比DD备份还原工具,TAR压缩还原工具更加小巧和灵活,但是不能备份MBR.当然可以通过重新安装GRUB来解决MBR的这一问题.同时,TAR的做法也是官方推荐的. 注意:一个硬盘启动时最新经过MBR( ...
- MYSQL 时间数据类型
- mysql数据类型和java数据类型匹配
Java数据类型和MySql数据类型对应一览 类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述 VARCHAR L+N VARCHAR java. ...
- Utuntu下Xshell使用+vi使用
记得上次Utuntu下Xshell环境没有搭建成功,这个又试试! 按照以前的方法测试Utuntu的ip;在本机安装Xshell 然后出现xshell连接虚拟机时,提示SSH服务器拒绝了密码 修改方法: ...
- [Typescript Kaop-ts] Use AOP in Vue Components with TypeScript and Kaop-ts
Aspect Oriented Programming, AOP, allows to reuse logic across an entire app in a very neat way, dec ...
- [Debug] Inspect and Style an Element in DevTools that Normally Disappears when Inactive
It’s handy to inspect an element in your browser’s DevTools when you need to experiment or tweak it’ ...