3981 动态最大子段和

 
 题目等级 : 钻石 Diamond
 
题目描述 Description

题目还是简单一点好...

有n个数,a[1]到a[n]。

接下来q次查询,每次动态指定两个数l,r,求a[l]到a[r]的最大子段和。

子段的意思是连续非空区间。

输入描述 Input Description

第一行一个数n。

第二行n个数a[1]~a[n]。

第三行一个数q。

以下q行每行两个数l和r。

输出描述 Output Description

q行,每行一个数,表示a[l]到a[r]的最大子段和。

样例输入 Sample Input

7
2 3 -233 233 -23 -2 233
4
1 7
5 6
2 5
2 3

样例输出 Sample Output

441
-2
233
3

数据范围及提示 Data Size & Hint

对于50%的数据,q*n<=10000000。

对于100%的数据,1<=n<=200000,1<=q<=200000。

a[1]~a[n]在int范围内,但是答案可能超出int范围。

数据保证1<=l<=r<=n。

空间128M,时间1s。

线段树求GSS模板题

一、一段长的区间的 GSS 有三种情况:
>1 完全在左子区间
>2 完全在右子区间
>3 横跨左右区间

二、需维护的信息:

max 区间GSS  ——用来更新情况1、2

max_l 区间左端点开始的GSS——用来更新情况3

max_r 区间右端点开始的GSS——用来更新情况3

sum 区间和——用来更新max_l,max_r

三、建树

1、初始化:区间需维护的信息最初都赋为输入值

2、合并区间信息

max:3中情况中的最大值

max_l:左区间的max_l, 左区间的sum+右区间max_l  取大

max_r 同理

四、查询

情况1、2很简单

情况3的合并与上面的合并区间信息同理

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m,opl,opr,cnt;
struct node
{
int l,r;
long long max,max_l,max_r,sum;
}e[];
void query(int k,long long & ans,long long & ans_l,long long & ans_r)
{
if(e[k].l>=opl&&e[k].r<=opr)
{
ans=e[k].max;
ans_l=e[k].max_l;
ans_r=e[k].max_r;
return;
}
int mid=e[k].l+e[k].r>>;
if(opr<=mid) query(k<<,ans,ans_l,ans_r);
else if(opl>mid) query((k<<)+,ans,ans_l,ans_r);
else
{
long long lch_max=,lch_max_r=,rch_max=,rch_max_l=,lch_max_l=,rch_max_r=;
query(k<<,lch_max,lch_max_l,lch_max_r);
query((k<<)+,rch_max,rch_max_l,rch_max_r);
ans=max(lch_max,rch_max);
ans=max(ans,lch_max_r+rch_max_l);
ans_l=max(lch_max_l,e[k<<].sum+rch_max_l);
ans_r=max(rch_max_r,e[(k<<)+].sum+lch_max_r);
}
}
void unionn(int k)
{
e[k].max=max(max(e[k<<].max,e[(k<<)+].max),e[k<<].max_r+e[(k<<)+].max_l);
e[k].max_l=max(e[k<<].max_l,e[k<<].sum+e[(k<<)+].max_l);
e[k].max_r=max(e[(k<<)+].max_r,e[(k<<)+].sum+e[k<<].max_r);
e[k].sum=e[k<<].sum+e[(k<<)+].sum;
}
void build(int k,int l,int r)
{
e[k].l=l,e[k].r=r;
if(l==r)
{
cin>>e[k].max;
e[k].max_l=e[k].max_r=e[k].sum=e[k].max;
return;
}
int mid=l+r>>;
build(k<<,l,mid);
build((k<<)+,mid+,r);
unionn(k);
}
int main()
{
scanf("%d",&n);
build(,,n);
scanf("%d",&m);
for(int i=;i<=m;i++)
{
scanf("%d%d",&opl,&opr);
long long ans=,ans_l=,ans_r=;
query(,ans,ans_l,ans_r);
printf("%lld\n",ans);
}
}

自己做的2个错误:

1、max_l的更新 : if 左区间的GSS是本身,max_l=max(左区间的max_l,左区间的sum+右区间的max_l)

else max_l=左区间的max_l

错因:例:左区间:5,8,-1,-1   右区间  1,1,1,1

错误方法的GSS=13   正确的GSS=15

2、在查询时ans,ans_l,ans_r的更新同max,max_l,max_r

因为max,max_l,max_r更新用到的左区间、右区间信息可以直接拿来用

而ans,ans_l,ans_r 更新用到的左区间、右区间信息不能直接拿来用,感觉比较棘手,实际只要在递归回溯时更新即可

codevs 3981 动态最大子段和的更多相关文章

  1. codevs 3981 动态最大子段和(线段树)

    题目传送门:codevs 3981 动态最大子段和 题目描述 Description 题目还是简单一点好... 有n个数,a[1]到a[n]. 接下来q次查询,每次动态指定两个数l,r,求a[l]到a ...

  2. codevs3981动态最大子段和(线段树)

    3981 动态最大子段和  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description 题目还是简单一点好... 有n个数,a ...

  3. codeVS 动态最大子段和

    题目链接:戳我 对于最大子段和,我们只需要维护四个变量--maxl,maxr,maxs,sum(分别表示区间最大前缀子段和,区间最大后缀子段和,区间最大子段和,区间所有数的和) 然后合并的时候是这样的 ...

  4. [codevs3981]动态最大子段和不带修改(线段树)

    解题关键:最大子段和需要多个信息维护. 注意查询时的pushup. #include<cstdio> #include<cstring> #include<algorit ...

  5. 线段树维护动态连续子段HDU1540

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=1540 #define IOS ios_base::sync_with_stdio(0); cin.tie( ...

  6. OI题目类型总结整理

    ## 本蒟蒻的小整理qwq--持续更新(咕咕咕) 数据结构 数据结构 知识点梳理 数据结构--线段树 推荐yyb dalao的总结--戳我 以后维护线段树还是把l,r写到struct里面吧,也别写le ...

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

  8. acm算法模板(1)

    1. 几何 4 1.1 注意 4 1.2 几何公式 4 1.3 多边形 6 1.4 多边形切割 9 1.5 浮点函数 10 1.6 面积 15 1.7 球面 16 1.8 三角形 17 1.9 三维几 ...

  9. ACM-ICPC竞赛模板

    为了方便打印,不再将代码放到代码编辑器里,祝你好运. ACM-ICPC竞赛模板(1) 1. 几何 4 1.1 注意 4 1.2 几何公式 4 1.3 多边形 6 1.4 多边形切割 9 1.5 浮点函 ...

随机推荐

  1. Luogu P1410 子序列

    题目大意: 给定一个长度为\(N\)(\(N\)为偶数)的序列,] 问能否将其划分为两个长度为\(\frac{N}{2}\)的严格递增子序列, 输入一共有\(50\)组数据,每组数据保证\(N \le ...

  2. HiHocoder1415 : 后缀数组三·重复旋律3 & Poj2774:Long Long Message

    题面 HiHocoder1415 Poj2774 Sol 都是求最长公共子串,\(hihocoder\)上讲的很清楚 把两个串拼在一起,中间用一个特殊字符隔开 那么答案就是排序后相邻两个不同串的后缀的 ...

  3. Office 365 Connectors 的使用与自定义开发

    前言 我相信很多人都看过<三国演义>,里面有很多引人入胜的故事和栩栩如生的人物,对我而言,曹操手下的一员猛将典韦实在让我印象深刻.例如,书中有一段描写典韦的作战经历: 时西面又急,韦进当之 ...

  4. 《Master Bitcoin》学习笔记02——比特币的交易模型

    比特币的交易模型 模型基本描述 前面一篇学习笔记01提到了一个交易模型(第三章的内容),在第五章中,除了对这个模型做个详细介绍之外,其实和我上一篇理解的交易模型差不多,一个交易包含输入与输出,比特币是 ...

  5. [.NET Core] 简单读取 json 配置文件

    简单读取 json 配置文件 背景 目前发现网上的 .NET Core 读取配置文件有点麻烦,自己想搞个简单点的. .NET Core 已经不使用之前的诸如 app.config 和 web.conf ...

  6. 创建和注册自定义 HTTP 模块

    本演练演示自定义 HTTP 模块的基本功能. 对于每个请求,都需要调用 HTTP 模块以响应 BeginRequest 和 EndRequest 事件. 因此,该模块在处理请求之前和之后运行. 如果 ...

  7. tensorflow实现最基本的神经网络 + 对比GD、SGD、batch-GD的训练方法

    参考博客:https://zhuanlan.zhihu.com/p/27853521 该代码默认是梯度下降法,可自行从注释中选择其他训练方法 在异或问题上,由于训练的样本数较少,神经网络简单,训练结果 ...

  8. WordPress让文本小工具支持简码

    WordPress 的 “文本” 小工具是非常常用的,可以添加一些自定义的文本或者 Html 代码.但很多时候,我们需要在文本小工具里使用简码来添加一些更加丰富的内容. 默认情况下,文本小工具是不支持 ...

  9. PAT 输出华氏-摄氏温度转换表

    输入2个正整数lower和upper(lower≤upper≤100),请输出一张取值范围为[lower,upper].且每次增加2华氏度的华氏-摄氏温度转换表. 温度转换的计算公式:C=5×(F−3 ...

  10. python 重要的日志模块logging

    一,logging模块简介 logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等:相比print,具备如下优点: 可以通过设置不同 ...