题面

You are given a sequence \(a_1,a_2,...,a_n\). (\(|A[i]| \leq 10000 , 1 \leq N \leq 10000\)). A query is defined as follows: Query(x1,y1,x2,y2) = \(Max{a_i+a_{i+1}+...+a_j;x_1 \leq i \leq y_1 , x_2 \leq j \leq y_2}\) and \(x_1 \leq x_2 , y_1 \leq y_2\). Given \(m\) queries (\(1 \leq M \leq 10000\)), your program must output the results of these queries.

题意

求所有左右端点分别在区间 \([x_1,y_1]\) 与 \([x_2,y_2]\) 的区间的最大连续子段和的最大值

思路

1° 两个区间不相交



答案显然是左边区间的 rmax+中间不重叠部分的 sum+右边区间的 lmax,即:\([x_1,y_1].rmax+[y_1,x_2].sum+[x_2,y_2].lmax\)

2° 两个区间相交



答案就会有三种情况

·① 答案区间为区间相交部分,即:\([x_2,y_1].max\)

·② 答案区间的左端点在相交部分左部,取相交部分左边的 rmax 和剩下区间的 lmax,再减掉加了两次的左边相交节点

即:\([x_1,x_2].rmax+[x_2,y_2].lmax-a_{x_2}\)

·③ 答案区间的右端点在相交部分右部,取相交部分右边的 lmax 和剩下区间的 rmax,再减掉加了两次的右边相交节点

即:\([y_1,y_2].lmax+[x_1,y_1].rmax-a_{y_1}\)

代码

/************************************************
*Author : lrj124
*Created Time : 2019.09.27.21:55
*Mail : 1584634848@qq.com
*Problem : spoj2916
************************************************/
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 10000 + 10;
struct seg { int l,r,sum,max; } tree[maxn<<2];
int T,n,q,a[maxn];
inline void pushup(int root) {
tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum;
tree[root].l = max(tree[root<<1].l,tree[root<<1|1].l+tree[root<<1].sum);
tree[root].r = max(tree[root<<1|1].r,tree[root<<1].r+tree[root<<1|1].sum);
tree[root].max = max(tree[root<<1].r+tree[root<<1|1].l,max(tree[root<<1].max,tree[root<<1|1].max));
}
inline void build(int l,int r,int root) {
if (l == r) {
tree[root] = { a[l],a[l],a[l],a[l] };
return;
}
int mid = l+r>>1;
build(l,mid,root<<1);
build(mid+1,r,root<<1|1);
pushup(root);
}
inline seg query(int l,int r,int ql,int qr,int root) {
if (ql > qr) return {0,0,0,0};
if (ql <= l && r <= qr) return tree[root];
int mid = l+r>>1;
if (mid >= qr) return query(l,mid,ql,qr,root<<1);
if (ql > mid) return query(mid+1,r,ql,qr,root<<1|1);
seg lson = query(l,mid,ql,qr,root<<1),rson = query(mid+1,r,ql,qr,root<<1|1),ans;
ans = { max(lson.l,rson.l+lson.sum),max(rson.r,lson.r+rson.sum),rson.sum+lson.sum,max(lson.r+rson.l,max(lson.max,rson.max)) };
return ans;
}
inline int solve(int l1,int r1,int l2,int r2) {
if (r1 < l2) return query(1,n,l1,r1,1).r+query(1,n,r1+1,l2-1,1).sum+query(1,n,l2,r2,1).l;
int ans = query(1,n,l2,r1,1).max;
if (l1 < l2) ans = max(ans,query(1,n,l1,l2,1).r+query(1,n,l2,r2,1).l-a[l2]);
if (r2 > r1) ans = max(ans,query(1,n,l1,r1,1).r+query(1,n,r1,r2,1).l-a[r1]);
return ans;
}
int main() {
for (scanf("%d",&T);T--;) {
memset(tree,0,sizeof(tree));
scanf("%d",&n);
for (int i = 1;i <= n;i++) scanf("%d",&a[i]);
build(1,n,1);
for (scanf("%d",&q);q--;) {
int l1,r1,l2,r2; scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
printf("%d\n",solve(l1,r1,l2,r2));
}
}
return 0;
}

【SP2916】Can you answer these queries V - 线段树的更多相关文章

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

  2. SPOJ 2916 Can you answer these queries V(线段树-分类讨论)

    题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出一个数列.每次查询最大子段和Sum[i,j],其中i和j满足x1<=i<=y1,x2<=j& ...

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

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

  4. SPOJ GSS1_Can you answer these queries I(线段树区间合并)

    SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...

  5. SPOJ 1557. Can you answer these queries II 线段树

    Can you answer these queries II Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://www.spoj.com/pr ...

  6. bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树

    2482: [Spoj1557] Can you answer these queries II Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 145 ...

  7. 【BZOJ2482】[Spoj1557] Can you answer these queries II 线段树

    [BZOJ2482][Spoj1557] Can you answer these queries II Description 给定n个元素的序列. 给出m个询问:求l[i]~r[i]的最大子段和( ...

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

  9. GSS4 2713. Can you answer these queries IV 线段树

    GSS7 Can you answer these queries IV 题目:给出一个数列,原数列和值不超过1e18,有两种操作: 0 x y:修改区间[x,y]所有数开方后向下调整至最近的整数 1 ...

随机推荐

  1. java消除整型数组中重复的元素,排序后输出新数组

    法一: import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(S ...

  2. 代码Verify简介

    序 对于开发者而言,编译代码和提交代码是必不可少的流程,同一个需求反复提交的情况也时常出现,那么怎么避免这种情况,且保证代码的质量,这就是Verify CI的目标.Verify表示认证验证的意思,结合 ...

  3. 面试题千变万化,为什么总是会问MySQL?

    前言 当你简历上写了 熟悉mysql关系型数据库时,那肯定免不了面试官对于myql索引.事务,慢查询等等的考察 那么到底什么是索引,索引的数据类型有哪些,它们的优缺点以及如何去排查那些慢SQL语句等, ...

  4. 疑难杂症1-去掉网站里的特殊编码&#65279

    编辑器:Visual Studio 2019项目框架:Net Core 3.1 + AutoFac 特殊符号&#65279,这是编码UTF-8 + BOM的特殊标记,是隐藏的,但是会被浏览器翻 ...

  5. Git报错问题集锦

    git merge合并时遇上refusing to merge unrelated histories的解决方案 如果git merge合并的时候出现refusing to merge unrelat ...

  6. PHP中interface的用处

    确实,PHP 接口是有它的目的的.   它们是契约,是给其他开发人员的说明手册.然而,还是很难理解接口有什么用.   基础 接口是抽象的类,无法直接实例化,但是可被实现.   这是一个基本的例 int ...

  7. 第二节:Centos下安装Tomcat8.5.57

    Tomcat8.5.57安装(手动配置版) 建议官网直接下载(http://tomcat.apache.org/),我本次配置使用的版本 apache-tomcat-8.5.57.tar.gz. 1. ...

  8. 一个调用其他activity的完整例子,使用了 onActivityResult和startActivityForResult

    https://blog.csdn.net/qq_32521313/article/details/52451364 Android startActivityForResult基本用法2016年09 ...

  9. .NET Core学习笔记(7)——Exception最佳实践

    1.为什么不要给每个方法都写try catch 为每个方法都编写try catch是错误的做法,理由如下: a.重复嵌套的try catch是无用的,多余的. 这一点非常容易理解,下面的示例代码中,O ...

  10. Python os.stat_float_times() 方法

    概述 os.stat_float_times() 方法用于决定stat_result是否以float对象显示时间戳.高佣联盟 www.cgewang.com 语法 stat_float_times() ...