前言

最近沉迷于数据结构,感觉数据结构很有意思。

正文

分析

先来分类讨论一下

1. \(x2<y1\)

如果 \(y1<x2\) 的话,答案 \(=\max \limits_{ y1 \leq x \leq y2} \{ s_i \} - \min \limits_{x1 \leq x \leq x2} \{ s_i \}\)

其中 \(s_i\) 表示 \(\sum\limits_{j=1}^{i} a_j\) ,就是俗称的前缀和

这个东西可以用线段树维护。

2. \(x2>=y1\)

这个怎么处理呢

答案 \(=\) \(\max \begin{cases}\max \limits_{ y1 \leq x \leq y2} \{ s_i \} - \min \limits_{x1 \leq x \leq y1} \{ s_i \}\\ \max \limits_{ x2 \leq x \leq y2} \{ s_i \} - \min \limits_{x1 \leq x \leq x2} \{ s_i \}\\ f(x,y)\end{cases}\)

这里的 \(f\) 函数就是最大子段和。

不会用线段树求最大子段和的可以看这里

最上面的 \(2\) 个也是可以用线段树来维护的。

代码

最后要注意的一点是前缀和,我们知道区间 \([i,j]\) 的和 $ = s_j-s_{i-1}$,而不是 $ = s_j-s_{i}$

这个怎么处理呢,我们发现我们的题目全部都是用 \(Max\) 函数的答案减去 \(Min\) 函数的答案,所以,我们可以把线段树维护的 \(\min\) 全部减去 \(a_{i}\)

现在这份代码就能 \(A\) 了

#include <bits/stdc++.h>
#define ls num<<1
#define rs num<<1|1
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
template<typename T>void write(T x){
if(x<0)putchar('-'),x*=-1;
if(x>9)write(x/10);
putchar(x%10+48);
}
template<typename T>void writen(T x){
write(x);
puts("");
}
const int MAXN=5e4+10;
struct Tree{
int l,r;
ll lans,rans,sum,ans,max,min;
}t[MAXN*4];
int a[MAXN],x,y,n,T,T_,l1,r1,l2,r2;
ll s[MAXN];
Tree pushup(Tree L,Tree R){
Tree z;
z.sum=L.sum+R.sum;
z.lans=max(L.lans,L.sum+R.lans);
z.rans=max(R.rans,R.sum+L.rans);
z.ans=max(max(L.ans,R.ans),L.rans+R.lans);
z.max=max(L.max,R.max);
z.min=min(L.min,R.min);
z.l=L.l;z.r=R.r;
return z;
}
void build(int l,int r,int num){
if(l==r){
t[num].l=l;
t[num].r=r;
t[num].sum=a[l];
t[num].lans=a[l];
t[num].rans=a[l];
t[num].ans=a[l];
t[num].max=s[l];
t[num].min=s[l]-a[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,ls);
build(mid+1,r,rs);
t[num]=pushup(t[ls],t[rs]);
}
Tree query(int num){
if(x<=t[num].l&&t[num].r<=y)return t[num];
if(t[rs].l>y)return query(ls);
if(t[ls].r<x)return query(rs);
return pushup(query(ls),query(rs));
}
ll Max(int num){
if(t[num].l>=x&&t[num].r<=y)return t[num].max;
if(t[ls].r<x)return Max(rs);
if(t[rs].l>y)return Max(ls);
return max(Max(ls),Max(rs));
}
ll Min(int num){
if(t[num].l>=x&&t[num].r<=y)return t[num].min;
if(t[ls].r<x)return Min(rs);
if(t[rs].l>y)return Min(ls);
return min(Min(ls),Min(rs));
}
ll Mx(int a,int b){
x=a;y=b;
return Max(1);
}
ll Mn(int a,int b){
x=a;y=b;
return Min(1);
}
ll qy(int a,int b){
x=a;y=b;
return query(1).ans;
}
int main(){
read(T);
while(T--){
read(n);
for(int i=1;i<=n;i++)read(a[i]);
for(int i=1;i<=n;i++)s[i]=s[i-1]+a[i];
build(1,n,1);
read(T_);
while(T_--){
read(l1);read(r1);read(l2);read(r2);
if(r1>l2)writen(max(qy(l2,r1),max(Mx(l2,r2)-Mn(l1,l2),Mx(r1,r2)-Mn(l1,r1))));
else writen(Mx(l2,r2)-Mn(l1,r1));
}
}
return 0;
}

后记

这篇题解如果有问题可以私信或评论,告诉我,一起完善

题解 SP2916 【GSS5 - Can you answer these queries V】的更多相关文章

  1. 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$,但是不保证端点所在的区间不重合 ...

  2. SPOJ GSS5 Can you answer these queries V

    Time Limit: 132MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Description You are g ...

  3. 【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 ...

  4. SPOJ GSS5 Can you answer these queries V ——线段树

    [题目分析] GSS1上增加区间左右端点的限制. 直接分类讨论就好了. [代码] #include <cstdio> #include <cstring> #include & ...

  5. [GSS5] Can you answer these queries V

    大力讨论. luogu上交spoj的题卡的一比... 难受 wa了好几次,原因大概首先求的是非空区间,不能乱和0取max,第二点是求无相交的解时,在两段求lmx和rmx的时候可以取max(0). 区间 ...

  6. SPOJ 2916 GSS5 - Can you answer these queries V

    传送门 解题思路 和GSS1相似,但需要巨恶心的分类讨论,对于x1<=y1< x2< =y2 这种情况 , 最大值应该取[x1,y1]的右端最大+[y1+1,x2-1]的和+[x2, ...

  7. 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[ ...

  8. [题解] SPOJ GSS1 - Can you answer these queries I

    [题解] SPOJ GSS1 - Can you answer these queries I · 题目大意 要求维护一段长度为 \(n\) 的静态序列的区间最大子段和. 有 \(m\) 次询问,每次 ...

  9. 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 ...

随机推荐

  1. classnames

    在React中编写模板时给标签添加class. 如果是固定的className="XX"就可以了. 如果要根据状态值动态应用或去除, 或使用多个class时就麻烦了. 可以使用cl ...

  2. Gre 隧道与 Keepalived

    这一篇文章是做了不少功课的. 什么是 Gre 隧道 什么是 Vrrp KeepAlived 是什么 用Keepalived 怎么玩 附录 什么是 Gre 隧道 GRE 隧道是一种 IP-2-IP 的隧 ...

  3. sms短信服务

    短信服务是app,电商类应用的基础功能.典型场景有: 用户注册,发送验证码 用户找回验证,发送验证码 用户账户异常,发送提示 用户账户变化,通知用户 短信服务开发有几个注意点: 供应商选型 短信模板 ...

  4. 强制迁移、合区 APP太强势伤害用户同时是否违法?

    APP太强势伤害用户同时是否违法?" title="强制迁移.合区 APP太强势伤害用户同时是否违法?"> 对于经常混迹在国内各大手游的玩家来说,"合区& ...

  5. JavaScript之三 - 语法

    1.block 一般就是{}包括起来的代码块,注意的是,js没有块作用域,但是有函数作用域,全局作用域. 2.var 1 var a = b = 1; 如: 123456 function () { ...

  6. 热更新,App双开,App隐藏,App试用 -- Replugin的实际应用(原创)

    热更新,App双开,App隐藏,App试用 -- Replugin的实际应用(原创) RePlugin是Qihoo 360公司的开源框架,原本目的是用于热更新.但是,这个框架提供的功能远远超出了热更新 ...

  7. sql01

    1.简介 2.外键 1)主键: 3.表间关联与外键 上面的两个表格通过厂家编号联系在一起,彼此相对独立.厂家编号就称为外键.厂家编号是厂家表的主键. 4.SQL 1)数据库登录 服务器名称选择:①机器 ...

  8. fsLayuiPlugin配置说明

    fsLayuiPlugin 是一个基于layui的快速开发插件,支持数据表格增删改查操作,提供通用的组件,通过配置html实现数据请求,减少前端js重复开发的工作. GitHub下载 码云下载 测试环 ...

  9. 【面试必备】硬核!30 张图解 HTTP 常见的面试题

    每日一句英语学习,每天进步一点点: 前言 在面试过程中,HTTP 被提问的概率还是比较高的.小林我搜集了 5 大类 HTTP 面试常问的题目,同时这 5 大类题跟 HTTP 的发展和演变关联性是比较大 ...

  10. JavaScript的函数(一)

    ,1,在javascript中,函数即对象.函数里面的参数可以是个函数,例如: data.sort(function(a,b){return a-b;}) 函数的返回值,return语句导致函数停止执 ...