传送门

线段树经典题。

就是让你求左端点在[l1,r1][l1,r1][l1,r1]之间,右端点在[l2,r2][l2,r2][l2,r2]之间且满足l1≤l2,r1≤r2l1\le l2,r1 \le r2l1≤l2,r1≤r2的最大子段和。


直接分类讨论就行了。

如果两个区间不相交的话,答案就是rmax(l1,l2)+sum(l2+1,l2−1)+lmax(l2,r2)rmax(l1,l2)+sum(l2+1,l2-1)+lmax(l2,r2)rmax(l1,l2)+sum(l2+1,l2−1)+lmax(l2,r2)。

如果相交的话,讨论一下就是max(max(rmax(l1,l2)+lmax(l2,r2)−val[l2],rmax(l1,r1)+lmax(r1,r2)−val[r1]),midmax(l2,r1))max(max(rmax(l1,l2)+lmax(l2,r2)-val[l2],rmax(l1,r1)+lmax(r1,r2)-val[r1]),midmax(l2,r1))max(max(rmax(l1,l2)+lmax(l2,r2)−val[l2],rmax(l1,r1)+lmax(r1,r2)−val[r1]),midmax(l2,r1))

代码:

#include<bits/stdc++.h>
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
#define N 10005
using namespace std;
inline int read(){
	int ans=0,w=1;
	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans*w;
}
int n,m,a[N],T_T;
struct Node{int l,r,ls,rs,ms,sum;}T[N<<2];
inline Node operator+(const Node&a,const Node&b){
	Node ret;
	ret.l=a.l,ret.r=b.r,ret.sum=a.sum+b.sum;
	ret.ls=max(a.ls,a.sum+b.ls);
	ret.rs=max(b.rs,b.sum+a.rs);
	ret.ms=max(max(a.ms,b.ms),a.rs+b.ls);
	return ret;
}
inline void build(int p,int l,int r){
	T[p].l=l,T[p].r=r;
	if(l==r){T[p].ls=T[p].rs=T[p].ms=T[p].sum=a[l];return;}
	build(lc,l,mid),build(rc,mid+1,r),T[p]=T[lc]+T[rc];
}
inline Node query(int p,int ql,int qr){
	if(ql>T[p].r||qr<T[p].l)return (Node){T[p].l,T[p].r,0,0,0,0};
	if(ql<=T[p].l&&T[p].r<=qr)return T[p];
	if(qr<=mid)return query(lc,ql,qr);
	if(ql>mid)return query(rc,ql,qr);
	return query(lc,ql,mid)+query(rc,mid+1,qr);
}
int main(){
	T_T=read();
	while(T_T--){
		n=read();
		for(int i=1;i<=n;++i)a[i]=read();
		build(1,1,n),m=read();
		while(m--){
			int l1=read(),r1=read(),l2=read(),r2=read();
			if(r1<l2){
				Node ansl=query(1,l1,r1),ansm=query(1,r1+1,l2-1),ansr=query(1,l2,r2);
				printf("%d\n",ansl.rs+ansm.sum+ansr.ls);
			}
			else{
				int ans=query(1,l2,r1).ms;
				if(l1<l2)ans=max(ans,query(1,l1,l2).rs+query(1,l2,r2).ls-a[l2]);
				if(r2>r1)ans=max(ans,query(1,l1,r1).rs+query(1,r1,r2).ls-a[r1]);
				printf("%d\n",ans);
			}
		}
	}

	return 0;
}

2018.10.16 spoj Can you answer these queries V(线段树)的更多相关文章

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

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

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

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

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

  4. SPOJ - GSS1-Can you answer these queries I 线段树维护区间连续和最大值

    SPOJ - GSS1:https://vjudge.net/problem/SPOJ-GSS1 参考:http://www.cnblogs.com/shanyr/p/5710152.html?utm ...

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

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

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

  7. SPOJ GSS1 - Can you answer these queries I(线段树维护GSS)

    Can you answer these queries I SPOJ - GSS1 You are given a sequence A[1], A[2], -, A[N] . ( |A[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. 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 ...

随机推荐

  1. JAVA 整合 SSM (Spring + SpringMVC + MyBatis)

    < 一 > POM 配置文件 ( 如果出现 JAR 包 引入错误, 请自行下载 ) <project xmlns="http://maven.apache.org/POM/ ...

  2. leetcode501

    /** * Definition for a binary tree node. * public class TreeNode { * public int val; * public TreeNo ...

  3. bootstrap左侧边栏

    之前都是想直接把导航栏放左边,但是会占一整行 网上找了好久,看到用bootstrap响应式布局,可以比较简单实现 经典的,可以参考:http://demo.qianduanblog.com/3150/ ...

  4. Spring DevTools 介绍

    Spring DevTools 介绍 Spring Boot包括一组额外的工具,可以使应用程序开发体验更加愉快. spring-boot-devtools模块可以包含在任何项目中,它可以节省大量的时间 ...

  5. as3 arguments.callee与... (rest)

    import flash.display.Sprite; var count:int = 1; ArgumentsExample() function ArgumentsExample() { fir ...

  6. 在mfc中picture控件中显示Mat图片<转>

    void ShowMatImgToWnd(CWnd* pWnd, cv::Mat img) { if(img.empty()) return; CRect drect; pWnd->GetCli ...

  7. 本地Facts

    我们可以通过Facts来获取目标主机的系统信息,当这些信息还不能满足我们的功能需要时,可以通过编写自定义的Facts模块来实现.当然,还有一个更简单的实现方法,就是通过本地Facts来实现.只需在目标 ...

  8. 将2020年交期的PR回写出来了

    OUT_pr表中的交期为2020年和2019年,不应该 回写的PR却回写出来了 优化如下:

  9. codeblocks不支持c++11的有效解决办法

    首先cb支持c++11编程开发,但是不支持编译 看了网上好多,说setting里面设置一下就好了,16.01版本我安装了带ide的不带IDE的,安了好多次,但是就是没有那个选项 找不到c++11那个选 ...

  10. 带最小值操作的栈 · Min Stack

    [抄题]: 实现一个带有取最小值min方法的栈,min方法将返回当前栈中的最小值. 你实现的栈将支持push,pop 和 min 操作,所有操作要求都在O(1)时间内完成. [思维问题]: [一句话思 ...