传送门

解题思路

和GSS1相似,但需要巨恶心的分类讨论,对于x1<=y1< x2< =y2 这种情况 , 最大值应该取[x1,y1]的右端最大+[y1+1,x2-1]的和+[x2,y2]的左端最大。对于x1< =x2< =y1<=y2,用四种情况,第一种是[x1,x2-1]的右端最大+[x2,y2]的左端最大,第二种是[x1,y1]的右端最大+[y1+1,y2]的左端最大,第三种是[x2,y1]的最大值,第四种是[x1,x2-1]的右端最大+[x2,y1]的和+[y1+1,y2]的左端最大。这四种情况取max即为答案。可以画图帮助理解。

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. using namespace std;
  6. const int MAXN = 10005;
  7. inline int rd(){
  8. int x=0,f=1;char ch=getchar();
  9. while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
  10. while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  11. return x*f;
  12. }
  13. int n,a[MAXN],T,m;
  14. struct Node{
  15. int lx,rx,sum,mx;
  16. Node(){
  17. lx=rx=sum=mx=0;
  18. }
  19. }node[MAXN<<2];
  20. inline void pushup(int x){
  21. node[x].sum=node[x<<1].sum+node[x<<1|1].sum;
  22. node[x].lx=max(node[x<<1].lx,node[x<<1].sum+node[x<<1|1].lx);
  23. node[x].rx=max(node[x<<1|1].rx,node[x<<1].rx+node[x<<1|1].sum);
  24. node[x].mx=max(max(node[x<<1].mx,node[x<<1|1].mx),node[x<<1].rx+node[x<<1|1].lx);
  25. }
  26. inline void build(int x,int l,int r){
  27. if(l==r){
  28. node[x].sum=node[x].lx=node[x].mx=node[x].rx=a[l];
  29. return;
  30. }
  31. int mid=l+r>>1;
  32. build(x<<1,l,mid);
  33. build(x<<1|1,mid+1,r);
  34. pushup(x);
  35. }
  36. inline Node query(int x,int l,int r,int L,int R){
  37. if(L<=l && r<=R) return node[x];
  38. int mid=l+r>>1;
  39. if(mid<L) return query(x<<1|1,mid+1,r,L,R);
  40. else if(mid>=R) return query(x<<1,l,mid,L,R);
  41. else {
  42. Node A=query(x<<1,l,mid,L,R);
  43. Node B=query(x<<1|1,mid+1,r,L,R);
  44. Node ans;
  45. ans.sum=A.sum+B.sum;
  46. ans.lx=max(A.lx,A.sum+B.lx);
  47. ans.rx=max(B.rx,B.sum+A.rx);
  48. ans.mx=max(max(A.mx,B.mx),A.rx+B.lx);
  49. return ans;
  50. }
  51. }
  52. inline Node solve(int x1,int y1,int x2,int y2){
  53. Node A=query(1,1,n,x1,y1);
  54. Node B=query(1,1,n,x2,y2);
  55. Node ans;
  56. if(y1<x2) {
  57. if(x2-1>=y1+1){
  58. Node C=query(1,1,n,y1+1,x2-1);
  59. ans.mx=A.rx+C.sum+B.lx;
  60. }
  61. else ans.mx=A.rx+B.lx;
  62. }
  63. else{
  64. Node C,D,E;
  65. if(x1<=x2-1) C=query(1,1,n,x1,x2-1);
  66. if(y1+1<=y2) D=query(1,1,n,y1+1,y2);
  67. E=query(1,1,n,x2,y1);
  68. ans.mx=max(max(E.mx,C.rx+E.sum+D.lx),max(C.rx+B.lx,A.rx+D.lx));
  69. }
  70. return ans;
  71. }
  72. int main(){
  73. T=rd();
  74. while(T--){
  75. n=rd();
  76. for(register int i=1;i<=n;i++) a[i]=rd();
  77. build(1,1,n);
  78. m=rd();
  79. while(m--){
  80. int x1=rd(),y1=rd(),x2=rd(),y2=rd();
  81. printf("%d\n",solve(x1,y1,x2,y2).mx);
  82. }
  83. }
  84. return 0;
  85. }

SPOJ 2916 GSS5 - Can you answer these queries V的更多相关文章

  1. SPOJ GSS5 Can you answer these queries V

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

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

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

  3. [GSS5] Can you answer these queries V

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

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

  5. 题解 SP2916 【GSS5 - Can you answer these queries V】

    前言 最近沉迷于数据结构,感觉数据结构很有意思. 正文 分析 先来分类讨论一下 1. \(x2<y1\) 如果 \(y1<x2\) 的话,答案 \(=\max \limits_{ y1 \ ...

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

  7. 「 SPOJ GSS3 」 Can you answer these queries III

    # 题目大意 GSS3 - Can you answer these queries III 需要你维护一种数据结构,支持两种操作: 单点修改 求一个区间的最大子段和 # 解题思路 一个区间的最大子段 ...

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

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

  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. 分析Hive表和分区的统计信息(Statistics)

    类似于Oracle的分析表,Hive中也提供了分析表和分区的功能,通过自动和手动分析Hive表,将Hive表的一些统计信息存储到元数据中. 表和分区的统计信息主要包括:行数.文件数.原始数据大小.所占 ...

  2. 2019-9-2-贡献自己的服务器搭建tor中转

    title author date CreateTime categories 贡献自己的服务器搭建tor中转 lindexi 2019-09-02 12:57:38 +0800 2018-2-13 ...

  3. ansible 安装及基本使用

    1.yum 安装 yum -y install epel-releaseyum -y install ansible ansible 配置秘钥 ssh-keygen -t rsa #直接回车不用设置密 ...

  4. 廖雪峰Java13网络编程-1Socket编程-3TCP多线程编程

    TCP多线程编程 一个ServerSocket可以和多个客户端同时建立连接,所以一个Server可以同时与多个客户端建立好的Socket进行双向通信. 因此服务器端,当我们打开一个Socket以后,通 ...

  5. 并发和多线程(二)--启动和中断线程(Interrupt)的正确姿势

    启动线程: 从一个最基本的面试题开始,启动线程到底是start()还是run()? Runnable runnable = () -> System.out.println(Thread.cur ...

  6. js '' ""的嵌套使用

    1.我需要拼接一个字符串,但是其中 单引号内包含了双引号,双引号内又包含了单引号变量 这时我们想到了可以用到HTML特殊转义字符 2.如下拼接 return '<input type=" ...

  7. java.util.concurrent中的几种同步工具类

    java.util.concurrent并发包中提供了一系列的的同步工具类,这些基础类不管是否能在项目中使用到,了解一下使用方法和原理对java程序员来说都是有必要的.博主在看<java并发编程 ...

  8. python中检测mysql的主键唯一性异常

    有两种方法: 1.直接检测是什么异常(查mysql文档找出异常代码) import os import mysql_operate.mysql_connect as mysql import re d ...

  9. Linux 静态IP配置

    静态配置文件# vim /etc/sysconfig/network-scripts/ifcfg-不同系统不一样主要几个配置TYPE=EthernetBOOTPROTO=static/noneNAME ...

  10. java基础之二维数组不定义列数

    有一种特殊的二维数组,它的行数确定,但是每行的列数不确定.这样的的数组实现方法:先创建制定行数,列数缺省的二维数组,然后对数组的每一行重新初始化.举例如下: package day5; //第二种定义 ...