传送门

线段树经典题。

就是让你求左端点在[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. HTML 标签元素的 align 属性

    align 属性规定段落中文本的对齐方式. 有 left  right center  justify 这些参数 left  right center  就是左对齐 右对齐 中间对齐 justify  ...

  2. as3 三行三列 布满9个为一个界面

    var n:int=int(iconIndex/3); e.x =(int(n/3)*3+iconIndex%3)*557; e.y = int(iconIndex / 3) % 3 * 260; i ...

  3. Simple2D-17(音乐播放器)嵌入 ImGui 库

    要把 ImGui 应用到项目中,先拷贝方框中的源文件到项目: 这些文件是 ImGui 的实现源码,可作为第三方库新建一个文件夹进行放置. 接下来是渲染部分的代码,项目可能使用 DirectX 或 Op ...

  4. Nginx 错误汇总

    1. Upstream timed out (110: Connection timed out) while reading response header from upstream 这种情况主要 ...

  5. 【转载】 Java并发编程:深入剖析ThreadLocal

    原文链接:http://www.cnblogs.com/dolphin0520/p/3920407.html感谢作者的辛苦总结! Java并发编程:深入剖析ThreadLocal 想必很多朋友对Thr ...

  6. 【341】Numpy 相关应用

    Numpy_01 >>> from numpy import pi >>> np.linspace(0, 2, 9) array([0. , 0.25, 0.5 , ...

  7. 使用robotium对android应用进行自动化测试

    所需要的环境: 1.eclipse 2.android development tools(ADT) 3.software develoment kit(SDK) 4.JDK 5.robotium 1 ...

  8. ArcGIS模型构建器案例学习笔记-字段处理模型集

    ArcGIS模型构建器案例学习笔记-字段处理模型集 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 由四个子模型组成 子模型1:判断字段是否存在 方法:python工 ...

  9. My Goal For SE

    2016年2月份,我开始进入软件工程的学习.作为一名大三学生,我对于此项课程,希望我自己能够通过制定学习目标来学好它. 首先,当我们在执行软件开发的时候,我们应该明确每个人的负责模块,我们应该明确自己 ...

  10. hdoj1260 Tickets (简单DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1260 思路: 很简单的DP题,状态方程也比较容易想到,用f[i]表示到第i个人所耗的最短时间,详见代码 ...