SPOJ 2916 Can you answer these queries V(线段树-分类讨论)
题目链接:http://www.spoj.com/problems/GSS5/
题意:给出一个数列。每次查询最大子段和Sum[i,j],其中i和j满足x1<=i<=y1,x2<=j<=y2,x1<=x2,y1<=y2。
思路:线段树的节点[L,R]保存LMax,RMax,Max,sum,表示左起最大值、右起最大值、区间最大值、区间数字和。更新比较简单。下面说查询。另外设置三个函数,可以查询任意区间[L,R]的最大值,以L开始向右最多到R的最大值、以R开始向左最多到L的最大值,设其分别为Q(L,R),QL(L,R),QR(L,R)。查询分两种情况讨论(设输入数组为d,S[i]表示d的前i项和):
(1)x2>y1: ans=QR(x1,y1)+S[x2-1]-S[y1]+QL(x2,y2);
(2)x2<=y1,那么有x1<=x2<=y1<=y2,则答案为下面三种情况的最大值:
a、x1<=i<=x2<=j<=y2,ans=QR(x1,x2)+QL(x2,y2)-d[x2];
b、x2<=i<=j<=y1,ans=Q(x2,y1);
c、x1<=i<=y1<=j<=y2,ans=QR(x1,y1)+QL(y1,y2)-d[y1]。
struct node
{
int LMax,RMax,Max,sum;
int L,R;
};
node a[N<<2];
int d[N],S[N];
int n;
void pushUp(int t)
{
if(a[t].L==a[t].R) return;
a[t].LMax=max(a[t*2].LMax,a[t*2].sum+a[t*2+1].LMax);
a[t].RMax=max(a[t*2+1].RMax,a[t*2+1].sum+a[t*2].RMax);
a[t].sum=a[t*2].sum+a[t*2+1].sum;
a[t].Max=max3(a[t*2].Max,a[t*2+1].Max,a[t*2].RMax+a[t*2+1].LMax);
}
void build(int t,int L,int R)
{
a[t].L=L;
a[t].R=R;
if(L==R)
{
a[t].sum=d[L];
a[t].LMax=a[t].RMax=a[t].Max=d[L];
return;
}
int mid=(L+R)>>1;
build(t*2,L,mid);
build(t*2+1,mid+1,R);
pushUp(t);
}
int queryL(int t,int L,int R)
{
if(a[t].L==L&&a[t].R==R) return a[t].LMax;
int mid=(a[t].L+a[t].R)>>1;
int ans;
if(R<=mid) ans=queryL(t*2,L,R);
else if(L>mid) ans=queryL(t*2+1,L,R);
else
{
ans=max(queryL(t*2,L,mid),S[mid]-S[L-1]+queryL(t*2+1,mid+1,R));
}
return ans;
}
int queryR(int t,int L,int R)
{
if(a[t].L==L&&a[t].R==R) return a[t].RMax;
int mid=(a[t].L+a[t].R)>>1;
int ans;
if(R<=mid) ans=queryR(t*2,L,R);
else if(L>mid) ans=queryR(t*2+1,L,R);
else
{
ans=max(queryR(t*2,L,mid)+S[R]-S[mid],queryR(t*2+1,mid+1,R));
}
return ans;
}
int query(int t,int L,int R)
{
if(a[t].L==L&&a[t].R==R) return a[t].Max;
int mid=(a[t].L+a[t].R)>>1;
int ans;
if(R<=mid) ans=query(t*2,L,R);
else if(L>mid) ans=query(t*2+1,L,R);
else
{
int x=query(t*2,L,mid);
int y=query(t*2+1,mid+1,R);
ans=max(x,y);
ans=max(ans,queryR(t*2,L,mid)+queryL(t*2+1,mid+1,R));
}
return ans;
}
int cal(int x1,int y1,int x2,int y2)
{
int a,b,c;
if(x2>y1)
{
a=queryR(1,x1,y1);
b=queryL(1,x2,y2);
return a+b+S[x2-1]-S[y1];
}
int ans;
a=queryR(1,x1,x2);
b=queryL(1,x2,y2);
ans=a+b-d[x2];
a=query(1,x2,y1);
ans=max(ans,a);
a=queryR(1,x1,y1);
b=queryL(1,y1,y2);
ans=max(ans,a+b-d[y1]);
return ans;
}
int main()
{
rush()
{
RD(n);
int i;
FOR1(i,n) RD(d[i]),S[i]=S[i-1]+d[i];
build(1,1,n);
int x1,y1,x2,y2;
int m;
RD(m);
while(m--)
{
RD(x1,y1); RD(x2,y2);
PR(cal(x1,y1,x2,y2));
}
}
}
SPOJ 2916 Can you answer these queries V(线段树-分类讨论)的更多相关文章
- 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[ ...
- SPOJ GSS5 Can you answer these queries V ——线段树
[题目分析] GSS1上增加区间左右端点的限制. 直接分类讨论就好了. [代码] #include <cstdio> #include <cstring> #include & ...
- 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 ...
- 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 ...
- 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 ...
- 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]| ≤ ...
- SPOJ GSS1 Can you answer these queries I[线段树]
Description You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A q ...
- 【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 ...
- SPOJ GSS3 Can you answer these queries III ——线段树
[题目分析] GSS1的基础上增加修改操作. 同理线段树即可,多写一个函数就好了. [代码] #include <cstdio> #include <cstring> #inc ...
随机推荐
- NYOJ-205 求余数 AC 分类: NYOJ 2014-02-02 12:30 201人阅读 评论(0) 收藏
这题目看一眼以为难度评级出错了,只是一个求余数的题目,,后来才发现,位数小于百万位,,,我还以为是大小小于百万呢,所以借鉴了另一大神的代码, 用大数,重点是同余定理: (a+b)mod m=((a m ...
- 【bzoj1008】[HNOI2008]越狱
1008: [HNOI2008]越狱 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7692 Solved: 3296[Submit][Status] ...
- nginx上如何支持.htaccess伪静态转向
我们知道在apache上有一个常用的功能.htaccess转向,只要apache编译的时候指明支持rewrite模块就可以了. 但是换到nginx上方法会有一点不一样,网上很多人说把.htaccess ...
- poj 2187
求凸包后枚举凸包上的点 #include <cstdio> #include <cstdlib> #include <cmath> #include <map ...
- themeforest 模板
如果给个人或一个客户使用就购买Regular License 多个项目或多人就徐需要购买Extended License,然后看你买html模版还是wordpress模版了.html需要你自己会编程将 ...
- ssh 远程 centos 乱码
今天,帮我们同学处理一下中文显示乱码的问题.这个是个国内Linux用户烦恼的问题,由于大部分的Linux发行版都是以英语为主体的,而且英文在通用性和稳定性上都比中文要好一些,各种奇怪的BUG也要少一点 ...
- Ruby Profiler 详解之 ruby-prof(I)
项目地址: ruby-prof 在上一篇 Ruby 中的 Profiling 工具中,我们列举了几种最常用的 Profiler,不过只是简单介绍,这一次详细介绍一下 ruby-prof 的使用方法. ...
- laravel where中多条件查询
1. http://www.mobanstore.com/doc/bianchengkaifa/119.html //初学laravel 发现他的查询构造器很好用 //如下 $user = DB::t ...
- iOS自定义发送消息输入框
简单的封装了一个,免得麻烦直接初始化就可以用了 ,有其他需求该里面参数就行了 WJEasyInputTextView.h , CGRectGetHeight([UIScreen mainScreen] ...
- Android Service学习
Android 中的 Service 全面总结 引用别人的博客:http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html 好文章 1.S ...