动态区间最大子段和

本文介绍了一道动态求解区间最大子段和的问题,详细阐述了问题背景、输入输出要求以及数据范围。针对这道题目,提出了区间最大子段和的三种情况,并说明了每个节点需要维护的信息。在建立树形结构的过程中,详细解释了如何合并区间信息。最后,讨论了查询过程,特别是当查询区间完全被搜索区间覆盖时,如何更新最大子段和的策略。
摘要由CSDN通过智能技术生成

题目描述 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。

一、一个区间的最大子段和有三种情况
1、左子区间的最大子段和
2、右子区间的最大子段和
3、横跨左右子区间

二、每个结点需要维护的信息
1、区间和sum
2、从区间左端点开始的最大子段和lgss
3、从区间右端点开始的最大子段和rgss
4、区间最大子段和gss

三、建树
1、遇到叶子节点就输入数据
2、合并区间信息
sum:左右子区间的区间和相加
lgss:max(左子区间的lgss,左子区间的sum + 右子区间的lgss)
rgss:max(右子区间的rgss,右子区间的sum + 左子区间的rgss)
gss:max(max(左子区间的最大子段和,右子区间的最大子段和),左子区间的右起最大子段和 + 右子区间的左起最大子段和)

四、查询
1、查询区间完全包含于搜索区间:更新ans和pre
pre:前一个搜索区间的从右端点开始的最大子段和(起连接左右两个区间的作用)
ans:到目前为止的最大子段和
ans的更新:要么就是该搜索区间的最大子段和,要么跨区间(跨区间即pre+当前搜索区间的lgss)
pre的更新:pre+该区间的sum 或 该区间的rgss

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const long long INF = 0x7FFFFFFFFFFFFFFF;
int n,q,a,b;
long long ans,pre;
struct node
{
   
    int l,r;
    long long gss,lgss,rgss,sum;
}tree[800001];

void Merge(int k)
{
   
    tree[k].gss = max(max
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值