链接:

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. docker安装和hub

    yum install wget wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum list dock ...

  2. python学习中

    python中的单引号.双引号.三引号的用法 网上也查找了资料,理解的都有些费劲 就自己验证了一下(主要是目前掌握的python知识,不知道什么时候会同时用到这三种引号) 用python3验证的 单引 ...

  3. Java多线程学习——wait方法(信号灯法/生产者消费者模式)

    信号灯法:以一个标志位来判断是否执行还是等待 public class TV { private String voice; //内容 private boolean flag=false; //信号 ...

  4. python每日一练:0005题

    第 0005 题: 你有一个目录,装了很多照片,把它们的尺寸变成都不大于 iPhone5 分辨率的大小. import cv2 import os def resize(path,sizeX,size ...

  5. js 自调函数

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  6. js if 判断的使用

    !DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> ...

  7. 分布式理论: CAP、BASE (转)

    分布式系统的CAP理论是由Eric Brewer于1999年首先提出的,又被称作布鲁尔定理(Brewer's theorem),CAP是对Consistency(一致性).Availability(可 ...

  8. dsu on tree 与长链剖分

    dsu on tree 对于树进行轻重链剖分,对于节点 $x$ ,递归所有轻儿子后消除其影响,递归重儿子,不消除其影响. 然后对于所有轻儿子的子树暴力,从而得到 $x$ 的答案. 对于要消除暴力消除即 ...

  9. JS调用PageMethods

    http://www.cnblogs.com/Ren_Lei/archive/2010/07/14/1777413.html JS调用PageMethods 操作步骤: 1.新建一个WebApplic ...

  10. wordpress数据库结构以及数据表之间的关系

    默认WordPress一共有以下11个表.这里加上了默认的表前缀 wp_ . wp_commentmeta:存储评论的元数据 wp_comments:存储评论 wp_links:存储友情链接(Blog ...