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[j] ; x1 <= i <= y1 , x2 j <= y2 and x1 <= x2 , y1 <= y2 }
分析:
其实画个图分类讨论一下之后,跟gss1基本一样。。。
注意到x1<=x2 , y1<=y2.
所以大致可以分为:
1.y1<x2:
直接计算区间[x1,y1]的右子区间连续最大和,[x2,y2]的左区间连续最大和,如果y1与x2之间有空隙的话,需要加上[y1+1,x2-1]的和。
2.y2>=x2:
考虑x1与x2的关系:
如果x1==x2,最大值可能出现在区间[x1,y1]的最大子段和,[x1,y1]的右区间连续最大和加上[y1+1,y2]的左区间连续最大和。
否则,考虑三个区间[x1,x2-1],[x2,y1],[y1+1,y2],这时考虑方式跟上面差不多,就不写出来了,具体可以看代码。
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull; #define debug puts("here")
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)
#define pb push_back
#define RD(n) scanf("%d",&n)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
#define All(vec) vec.begin(),vec.end()
#define MP make_pair
#define PII pair<int,int>
#define PQ priority_queue
#define cmax(x,y) x = max(x,y)
#define cmin(x,y) x = min(x,y)
#define Clear(x) memset(x,0,sizeof(x))
/* #pragma comment(linker, "/STACK:1024000000,1024000000") int size = 256 << 20; // 256MB
char *p = (char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p) ); */ /******** program ********************/ const int MAXN = 100005; int a[MAXN]; struct segTree{
int l,r,lx,rx,mx,sum;
inline int mid(){
return (l+r)>>1;
}
}tree[MAXN<<2]; inline void Union(segTree& now,segTree l,segTree r){
now.lx = max( l.lx , l.sum+max(0,r.lx) );
now.rx = max( r.rx , r.sum+max(0,l.rx) );
now.mx = max( l.rx+r.lx , max(l.mx,r.mx) );
now.sum = l.sum+r.sum;
} void build(int l,int r,int rt){
tree[rt].l = l;
tree[rt].r = r;
if(l==r){
tree[rt].lx = tree[rt].rx = tree[rt].sum = tree[rt].mx = a[l];
return;
}
int mid = tree[rt].mid();
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
Union(tree[rt],tree[rt<<1],tree[rt<<1|1]);
} void modify(int pos,int c,int rt){
if(tree[rt].l==tree[rt].r){
tree[rt].lx = tree[rt].rx = tree[rt].mx = tree[rt].sum = c;
return;
}
int mid = tree[rt].mid();
if(pos<=mid)modify(pos,c,rt<<1);
else modify(pos,c,rt<<1|1);
Union(tree[rt],tree[rt<<1],tree[rt<<1|1]);
} segTree ask(int l,int r,int rt){
if(l<=tree[rt].l&&r>=tree[rt].r)
return tree[rt];
int mid = tree[rt].mid();
segTree ans;
if(r<=mid) ans = ask(l,r,rt<<1);
else if(l>mid) ans = ask(l,r,rt<<1|1);
else{
segTree a = ask(l,r,rt<<1);
segTree b = ask(l,r,rt<<1|1);
Union( ans,a,b );
}
Union(tree[rt],tree[rt<<1],tree[rt<<1|1]);
return ans;
} int main(){ #ifndef ONLINE_JUDGE
freopen("sum.in","r",stdin);
//freopen("sum.out","w",stdout);
#endif int m,n,x,y,c,d;
int ncase;
RD(ncase);
while(ncase--){
RD(n);
rep1(i,n)
RD(a[i]);
build(1,n,1);
RD(m);
segTree ca,cb,cc;
while(m--){
RD4(x,y,c,d);
int sum = 0;
if(y>=c){
if(x<c){
ca = ask(x,c-1,1);
cb = ask(c,y,1);
sum = max( ca.rx+cb.lx,cb.mx );
if(y<d){
cc = ask(y+1,d,1);
int tmp = max( max(0,ca.rx)+cb.sum+cc.lx , cb.rx+cc.lx );
sum = max( sum,tmp );
}
}else{
ca = ask(c,y,1);
sum = ca.mx;
if(y<d){
cc = ask(y+1,d,1);
sum = max(sum,ca.rx+cc.lx);
}
}
}else{
ca = ask(x,y,1);
cb = ask(c,d,1);
sum = ca.rx+cb.lx;
if(y+1<c){
cc = ask(y+1,c-1,1);
sum += cc.sum;
}
}
printf("%d\n",sum);
}
} return 0;
}
GSS5 spoj 2916. Can you answer these queries V 线段树的更多相关文章
- SPOJ 2916 Can you answer these queries V(线段树-分类讨论)
题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出一个数列.每次查询最大子段和Sum[i,j],其中i和j满足x1<=i<=y1,x2<=j& ...
- 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 GSS5 Can you answer these queries V ——线段树
[题目分析] GSS1上增加区间左右端点的限制. 直接分类讨论就好了. [代码] #include <cstdio> #include <cstring> #include & ...
- 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 ...
- SPOJ GSS3 Can you answer these queries III ——线段树
[题目分析] GSS1的基础上增加修改操作. 同理线段树即可,多写一个函数就好了. [代码] #include <cstdio> #include <cstring> #inc ...
- SPOJ GSS2 Can you answer these queries II ——线段树
[题目分析] 线段树,好强! 首先从左往右依次扫描,线段树维护一下f[].f[i]表示从i到当前位置的和的值. 然后询问按照右端点排序,扫到一个位置,就相当于查询区间历史最值. 关于历史最值问题: 标 ...
随机推荐
- android AsyncHttpClient 开源框架的使用
AsyncHttpClient 1.在很多时候android都需要进行网络的操作,而android自带的HttpClient可以实现,但要进行很多网络连接的时候(如:下载很多图片),就需要线程池来进行 ...
- ORA-04091: 表 发生了变化, 触发器/函数不能读它
触发器中新调用了一个存储过程. 触发器: create or replace trigger tr_credits_wzclorder_clwzjk after update on app_wzclo ...
- J2534 Pass-Thru Vehicle Programming ( SAE J1962 connector and Protocol )
SAE J1962—Diagnostic Connector SAE J1850—Class B Data Communications Network Interface SAE J1939—Tru ...
- C++学习笔记之字符函数库cctype
C++从C语言继承了一个与字符相关的.非常方便的函数软件包,它可以简化诸如确定字符是否为大写字母.数字.标点符号等工作,这些函数原型是在头文件cctype(老式风格ctype.h)中定义的. 下表对这 ...
- easy Html5 - Jquery Mobile之ToolBars(Header and Footer)
jquery 在web js框架上的风暴还在继续却也随着移动终端走向了mobile:那么jquery mobile到底包括些什么呢 简介工具栏是在移动网站和应用中的头部,尾部或者内容中的工具条:Jqu ...
- android获取/更改gps和WIFI状态
一.WIFI状态的获取和更改 适用于 SDK1.0 , SDK1.5 1.获取WIFI状态 方法1:通过WifiManager进行操作 1WifiManager wifiManager = (Wifi ...
- Java HttpClient使用小结
httpclient是apache的一个项目:http://hc.apache.org/ 文档比較完好:http://hc.apache.org/httpcomponents-client-ga/tu ...
- SQL SERVER中查找某关键词位于哪些存储过程或函数
USE [MYDB] go SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_type='PROCEDURE' AND routine_d ...
- 对cocos2d 之autorelease\ratain\release的理解
前言: 三种情况,引出问题 new出来的对象需要释放,而释放时,如果有其他人引用了这个对象,再次使用这个对象时,则会导致无效指针报错. 于是有了引用计数的施放管理机制. 对 ...
- linux 内核调试方法
http://my.oschina.net/fgq611/blog/113249 http://my.oschina.net/fgq611/blog/112929