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_source=itdadao&utm_medium=referral
题意:
给定一个数列,很多次询问,问某个区间中最大的连续和是多少。
思路
线段树,每个线段树的节点要维护对应区间的最大值ans,与左端点相连的最大值lv,与右端点相连的最大值rv,还有区间全部的总和V;
这个V用在pushup中。
这个pushup的操作是:
void pushup(int rt){
p[rt].v = p[rt<<].v + p[rt<<|].v;
p[rt].lv = max(p[rt<<].lv, p[rt<<].v + p[rt<<|].lv);
p[rt].rv = max(p[rt<<|].rv, p[rt<<|].v + p[rt<<].rv);
p[rt].ans = max3(p[rt<<].ans, p[rt<<|].ans, p[rt<<].rv + p[rt<<|].lv);
}
每个区间的lv 就是 (左子区间的lv ,左子区间v + 右子区间的lv) 中的较大者。rv同理。
每个区间的ans就是,(左子区间的ans,右子区间的ans, 左子区间和右子区间中间连接的那段)中的较大者。
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert>
using namespace std;
//#pragma GCC optimize(3)
//#pragma comment(linker, "/STACK:102400000,102400000") //c++
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue
#define max3(a,b,c) max(max(a,b),c) typedef long long ll;
typedef unsigned long long ull; typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n' #define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行
#define REP(i , j , k) for(int i = j ; i < k ; ++i)
//priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //
const ll nmos = 0x80000000; //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //
const int mod = 1e9+;
const double esp = 1e-;
const double PI=acos(-1.0); template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} /*-----------------------showtime----------------------*/
const int maxn = ;
int a[maxn];
struct node
{
int lv,rv,v;
int ans;
node(){
lv = rv = v = ans = -inf;
}
}p[maxn<<];
void pushup(int rt){
p[rt].v = p[rt<<].v + p[rt<<|].v;
p[rt].lv = max(p[rt<<].lv, p[rt<<].v + p[rt<<|].lv);
p[rt].rv = max(p[rt<<|].rv, p[rt<<|].v + p[rt<<].rv);
p[rt].ans = max3(p[rt<<].ans, p[rt<<|].ans, p[rt<<].rv + p[rt<<|].lv);
}
void build(int l,int r,int rt){
if(l==r){
p[rt].v = p[rt].lv = p[rt].rv = p[rt].ans = a[l];
return;
}
int mid = (l + r)>>;
build(l,mid,rt<<);
build(mid+,r,rt<<|);
pushup(rt);
}
node query(int l,int r,int rt,int L,int R){
if(l>=L&&r<=R){
return p[rt];
}
int mid = (l + r)>>;
node t1,t2,res;
t1.ans = -inf,t2.ans = -inf;
if(mid >= L)t1 = query(l,mid,rt<<,L,R);
if(mid < R) t2 = query(mid+,r,rt<<|,L,R);
if(t1.ans!=-inf && t2.ans!=-inf){
res.lv = max(t1.lv, t1.v + t2.lv);
res.rv = max(t2.rv, t2.v + t1.rv);
res.v = t1.v + t2.v;
res.ans = max3(t1.ans, t2.ans, t1.rv + t2.lv);
}
else if(t1.ans!=-inf){
res = t1;
}
else if(t2.ans!=-inf){
res = t2;
}
return res;
}
int main(){
int n,m;
scanf("%d", &n);
for(int i=; i<=n; i++){
scanf("%d", &a[i]);
}
build(,n,);
scanf("%d", &m);
while(m--){
int l,r;
scanf("%d%d", &l, &r);
printf("%d\n", query(,n,,l,r).ans);
}
return ;
}
SPOJ - GSS1
SPOJ - GSS1-Can you answer these queries I 线段树维护区间连续和最大值的更多相关文章
- 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 ...
- SPOJ GSS1 Can you answer these queries I ——线段树
[题目分析] 线段树裸题. 注意update的操作,写结构体里好方便. 嗯,没了. [代码] #include <cstdio> #include <cstring> #inc ...
- Spoj 1557 Can you answer these queries II 线段树 随意区间最大子段和 不反复数字
题目链接:点击打开链接 每一个点都是最大值,把一整个序列和都压缩在一个点里. 1.普通的区间求和就是维护2个值,区间和Sum和延迟标志Lazy 2.Old 是该区间里出现过最大的Sum, Oldlaz ...
- 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 ...
- 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 ...
- Can you answer these queries I SPOJ - GSS1 (线段树维护区间连续最大值/最大连续子段和)
You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A query is defi ...
- 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 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 ...
随机推荐
- Promise异步编程解决方案
Promise是ES6中新增的异步编程解决方案,体现在代码中它是一个对象,可以通过 Promise 构造函数来实例化. 其最基本的使用 new Promise(function(resolve,rej ...
- HTTP文件上传原理
前言 对于这块知识点,我一直都是模糊的,不是非常清楚的.在平时的工作中,遇到上传的问题,也没有深入的去研究过,也都是直接用别人封装好的类来完成自己的工作.某一天,看了本书,说到这个知识点,一脸茫然,觉 ...
- iOS Xcode6 新建OC Category文件
首先:File -> New File 接下来界面如下,选择Objective-C File,然后Next 在这里选择 Category 即可
- Keil uVision4 ——如何新建一个项目
一.打开Keil4软件,点击Project,再点击New μVision Projrct. 二.新建一个文件夹,并在里面输入这个项目的名字. 三.点击Intel,根据实际情况选择,这里选择的是80/8 ...
- [Hei.Captcha] Asp.Net Core 跨平台验证码实现
写在前面 说起来比较丢脸.我们有个手机的验证码发送逻辑需要使用验证码,这块本来项目里面就有验证码绘制逻辑,.Net Framework的,使用的包是System.Drawing,我把这验证码绘制逻辑复 ...
- PID算法 旋转倒立摆与平衡车的区别。此贴后边会更新。
我做PID算法的背景和经历:本人之前电子信息科学与技术专业,对控制方向颇感兴趣,刚上大学时听到实验室老师说PID算法,那年在暑假集训准备全国电子设计竞赛,我正在练习做一个以前专科的题目,帆板角度控制系 ...
- JavaSE之——并没有多维数组
近日在读<疯狂Java讲义>精粹第二版,部分语述摘自其中,自己边敲边理解 前言 我们知道,Java语言支持的类型有两种: 1.基本类型(即八大基本数据类 ...
- Layui多文件上传进度条
Layui原生upload模块不支持文件上传进度条显示,百度,谷歌找了一下不太适用.后面找到一个别人修改好的JS,替换上去,修改一下页面显示即可使用,一下是部分代码 HTML: <div cla ...
- coursera课程《how to learning 怎么学习》 总结
总体来说,学完课程没有茅舍顿开的感觉,而是更加印证了之前的那个认知:大道至简,践则无敌,很多的学习方法上学的时候老师都教过我们,关键是我们能否坚持执行.课程讲了很多脑科学有关学习的知识,但对于我们实践 ...
- python数据类型图解