链接:

https://vjudge.net/problem/SPOJ-GSS1

题意:

You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A query is defined as follows:

Query(x,y) = Max { a[i]+a[i+1]+...+a[j] ; x ≤ i ≤ j ≤ y }.

Given M queries, your program must output the results of these queries.

区间最大子段和

思路:

线段树维护,区间总和, 区间中间最大和, 区间以左端点为起点的最大和, 区间以有端的结束的最大和.

向上的维护代码

void PushUp(int root)
{
Seg[root].sum = Seg[root<<1].sum+Seg[root<<1|1].sum;
//区间和
Seg[root].midmax = max(Seg[root<<1].rmax+Seg[root<<1|1].lmax, max(Seg[root<<1].midmax, Seg[root<<1|1].midmax));
//区间中间和,左节点中间和,右节点中间和,左节点右边和加右节点左边和,三个取最大
Seg[root].lmax = max(Seg[root<<1].sum+Seg[root<<1|1].lmax, Seg[root<<1].lmax);
//区间左边和, 左节点左边和,左节点区间和加右节点左边和,两个取最大
Seg[root].rmax = max(Seg[root<<1|1].sum+Seg[root<<1].rmax, Seg[root<<1|1].rmax);
//区间右边的, 右节点右边和,右节点区间和加左节点右边和,两个最大
}

查询学到了新操作,返回结构体,挺好用的

代码:

/*
*线段树维护区间最大子段和
* 模板
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long LL; const int MAXN = 5e4+10;
const int INF = 1e9+10;
const int NINF = -1e9; struct SegmentTree
{
LL sum;//区间全部和
LL midmax;//区间中间值最大和
LL lmax;//以左端点为起点的最大和
LL rmax;//以右端点为终点的最大和
}Seg[MAXN*4];
LL a[MAXN];
int n, q; void PushUp(int root)
{
Seg[root].sum = Seg[root<<1].sum+Seg[root<<1|1].sum;
//区间和
Seg[root].midmax = max(Seg[root<<1].rmax+Seg[root<<1|1].lmax, max(Seg[root<<1].midmax, Seg[root<<1|1].midmax));
//区间中间和,左节点中间和,右节点中间和,左节点右边和加右节点左边和,三个取最大
Seg[root].lmax = max(Seg[root<<1].sum+Seg[root<<1|1].lmax, Seg[root<<1].lmax);
//区间左边和, 左节点左边和,左节点区间和加右节点左边和,两个取最大
Seg[root].rmax = max(Seg[root<<1|1].sum+Seg[root<<1].rmax, Seg[root<<1|1].rmax);
//区间右边的, 右节点右边和,右节点区间和加左节点右边和,两个最大
} void Build(int root, int l, int r)
{
if (l == r)
{
Seg[root].sum = Seg[root].midmax = Seg[root].lmax = Seg[root].rmax = a[l];
return;
}
int mid = (l+r)/2;
Build(root<<1, l, mid);
Build(root<<1|1, mid+1, r);
PushUp(root);
} SegmentTree Query(int root, int l, int r, int ql, int qr)
{
SegmentTree lt = {NINF, NINF, NINF, NINF}, rt = {NINF, NINF, NINF, NINF}, re = {NINF, NINF, NINF, NINF};
if (ql <= l && r <= qr)
return Seg[root];
int mid = (l+r)/2;
if (ql <= mid)
lt = Query(root<<1, l, mid, ql, qr);
if (qr > mid)
rt = Query(root<<1|1, mid+1, r, ql, qr);
re.sum = lt.sum+rt.sum;
re.midmax = max(lt.rmax+rt.lmax, max(lt.midmax, rt.midmax));
re.lmax = max(lt.sum+rt.lmax, lt.lmax);
re.rmax = max(rt.sum+lt.rmax, rt.rmax);
return re;
} int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for (int i = 1;i <= n;i++)
cin >> a[i];
Build(1, 1, n);
cin >> q;
int l, r;
while (q--)
{
cin >> l >> r;
SegmentTree res = Query(1, 1, n, l, r);
cout << max(res.midmax, max(res.lmax, res.rmax)) << endl;
} return 0;
}

SPOJ-GSS1-Can you answer these queries 1的更多相关文章

  1. [题解] SPOJ GSS1 - Can you answer these queries I

    [题解] SPOJ GSS1 - Can you answer these queries I · 题目大意 要求维护一段长度为 \(n\) 的静态序列的区间最大子段和. 有 \(m\) 次询问,每次 ...

  2. 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]| ≤ ...

  3. 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 ...

  4. SPOJ GSS1 Can you answer these queries I

    Time Limit: 115MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Description You are g ...

  5. SPOJ GSS1 Can you answer these queries I ——线段树

    [题目分析] 线段树裸题. 注意update的操作,写结构体里好方便. 嗯,没了. [代码] #include <cstdio> #include <cstring> #inc ...

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

  7. GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树

    GSS7Can you answer these queries VII 给出一棵树,树的节点有权值,有两种操作: 1.询问节点x,y的路径上最大子段和,可以为空 2.把节点x,y的路径上所有节点的权 ...

  8. 线段树 SP1043 GSS1 - Can you answer these queries I

    SP1043 GSS1 - Can you answer these queries I 题目描述 给出了序列A[1],A[2],-,A[N]. (a[i]≤15007,1≤N≤50000).查询定义 ...

  9. GSS3 SPOJ 1716. Can you answer these queries III gss1的变形

    gss2调了一下午,至今还在wa... 我的做法是:对于询问按右区间排序,利用splay记录最右的位置.对于重复出现的,在splay中删掉之前出现的位置所在的节点,然后在splay中插入新的节点.对于 ...

  10. GSS1 spoj 1043 Can you answer these queries I 最大子段和

    今天下午不知道要做什么,那就把gss系列的线段树刷一下吧. Can you answer these queries I 题目:给出一个数列,询问区间[l,r]的最大子段和 分析: 线段树简单区间操作 ...

随机推荐

  1. python - 代码调试的好帮手sys._getframe()

    python 的调试,令人非常忧伤,通过将输出路径打印的方式,可以提高很大的方便性: import sys #coding=utf-8 def get_cur_info(): print sys._g ...

  2. Delphi XE2 之 FireMonkey 入门(36) - 控件基础: TForm

    Delphi XE2 之 FireMonkey 入门(36) - 控件基础: TForm 当我第一次读取 Form1.StyleLookup 并期待出现 "formstyle" 时 ...

  3. HTTP学习记录:一、协议基础

    学习资源主要为:@小坦克HTTP相关博客 1.HTTP简介: HTTP协议是Hyper Text Transfer Portocol(超文本传输协议)的缩写,它是一种通信协议,允许将超文本(即:htm ...

  4. nginx重要特性

    反向代理负载均衡实现高并发 1.反向代理反向代理(Reverse Proxy)方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器:并将从服务器上得到的结果返回给 ...

  5. 关于win10系统如何调用debug查看CPU汇编指令和内存

    下载安装DOSBox.网上提供下载地址:DOSBOX Debug是DOS(Disk Operating System,磁盘操作系统).windows提供的实模式(8086方式)程序的调试工具.使用它, ...

  6. [Git] 023 Re:从零开始的 rebase 命令

    1. 开门见山 我新建了一个本地仓库,并进行了一些操作 当前情况 查看(直观但不明了) 上图的第二条 "log" 命令详见 [Git] 024 log 命令的补充 的 " ...

  7. SQLSERVER 备份恢复之后提示缺少创建表权限的问题解决

    1. 同事这边出现异常: 执行功能是报错, 这个错误 应该是创建临时表时没有权限触发的. 方法应该很简单 缺少权限增加权限即可 2. 这里需要使用sa 或者是 具有sa权限的用户登录 打开 数据库级别 ...

  8. C#中的委托和事件(一)——delegate

    前言 来说一说委托(delegate)和事件(event),本篇采取的形式是翻译微软Delegate的docs中的重要部分(不要问我为什么微软的docs有中文还要读英文,因为读中文感觉自己有阅读障碍- ...

  9. oracle跟SQL Server 2005 的区别

    Oracle与Sql server的区别   一直搞不明白Oracle数据库和sql server的区别,今天我特意查资料把他们的区别整理出来 Oracle数据库:Oracle Database,又名 ...

  10. [luogu5339] [TJOI2019]唱、跳、rap和篮球(容斥原理+组合数学)(不用NTT)

    [luogu5339] [TJOI2019]唱.跳.rap和篮球(容斥原理+组合数学)(不用NTT) 题面 略 分析 首先考虑容斥,求出有i堆人讨论的方案. 可以用捆绑法,把每堆4个人捆绑成一组,其他 ...