题目链接:戳我

对于最大子段和,我们只需要维护四个变量——maxl,maxr,maxs,sum(分别表示区间最大前缀子段和,区间最大后缀子段和,区间最大子段和,区间所有数的和)

然后合并的时候是这样的:

t[x].sum=t[ls(x)].sum+t[rs(x)].sum;
t[x].maxs=max(max(t[ls(x)].maxs,t[rs(x)].maxs),t[ls(x)].maxr+t[rs(x)].maxl);
t[x].maxl=max(t[ls(x)].maxl,t[ls(x)].sum+t[rs(x)].maxl);
t[x].maxr=max(t[rs(x)].maxr,t[ls(x)].maxr+t[rs(x)].sum);

然后想要强调的是,询问的时候一定不能像普通线段树那样写,因为我们需要考虑三种情况。一种是该节点表示区间的答案应该从左子节点表示区间取得,一种是该节点表示区间的答案是应该从右子节点表示区间取得,一种是该节点表示区间的答案应该从左右节点中合并取得。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 2000010
using namespace std;
int n,m;
long long a[MAXN];
struct Node{long long maxs,maxl,maxr,sum;}t[MAXN<<2];
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
inline void push_up(int x)
{
t[x].sum=t[ls(x)].sum+t[rs(x)].sum;
t[x].maxs=max(max(t[ls(x)].maxs,t[rs(x)].maxs),t[ls(x)].maxr+t[rs(x)].maxl);
t[x].maxl=max(t[ls(x)].maxl,t[ls(x)].sum+t[rs(x)].maxl);
t[x].maxr=max(t[rs(x)].maxr,t[ls(x)].maxr+t[rs(x)].sum);
}
inline void build(int x,int l,int r)
{
if(l==r)
{
t[x].sum=t[x].maxs=t[x].maxl=t[x].maxr=a[l];
return;
}
int mid=(l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
push_up(x);
//printf("x=%d l=%d r=%d maxs=%d maxl=%d maxr=%d sum=%d\n",x,l,r,t[x].maxs,t[x].maxl,t[x].maxr,t[x].sum);
}
inline Node query(int x,int l,int r,int ll,int rr)
{
//printf("x=%d l=%d r=%d ll=%d rr=%d\n",x,l,r,ll,rr);
if(ll==l&&r==rr) {return t[x];}
int mid=(l+r)>>1;
if(rr<=mid) return query(ls(x),l,mid,ll,rr);
else if(mid<ll) return query(rs(x),mid+1,r,ll,rr);
else
{
Node lson=query(ls(x),l,mid,ll,mid),rson=query(rs(x),mid+1,r,mid+1,rr),ans;
ans.sum=lson.sum+rson.sum;
ans.maxs=max(max(lson.maxs,rson.maxs),lson.maxr+rson.maxl);
ans.maxl=max(lson.maxl,lson.sum+rson.maxl);
ans.maxr=max(rson.maxr,lson.maxr+rson.sum);
return ans;
}
} int main()
{
freopen("ce1.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
long long l,r;
scanf("%lld%lld",&l,&r);
printf("%lld\n",query(1,1,n,l,r).maxs);
}
return 0;
}

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

  1. codevs 3981 动态最大子段和

    3981 动态最大子段和 http://codevs.cn/problem/3981/    题目等级 : 钻石 Diamond   题目描述 Description 题目还是简单一点好... 有n个 ...

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

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

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

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

  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. UGUI 自动布局的重叠BUG

    1,父级使用了verticalLayout(注意没有ContentSizeFilter),子级使用了ContentSizeFilter时,点击Apply常常发现,本来布局好的UI突然重叠到了一起,或位 ...

  2. golang 函数和方法

    由于自己是搞python开发的,所以在学习go时,当看到函数和方法时,顿时还是挺蒙的,因为在python中并没有明显的区别,但是在go中却是两个完全不同的东西.在官方的解释中,方法是包含了接收者的函数 ...

  3. 附上SQL Server的存储过程例子

    代码如下,看了就明白: --添加项目大类存储过程 use chaiqianD2 go if object_id('p_InsertBigType', 'p') is not null drop pro ...

  4. 4600007972内销新单未取进FP

    1.首先检查 in_sales_order表: select * from in_sales_order where so_id='04600007972'发现没有数据 2.接着检查从SAP导数的步骤 ...

  5. cdoj32-树上战争(Battle on the tree) 【记忆化搜索】

    http://acm.uestc.edu.cn/#/problem/show/32 树上战争(Battle on the tree) Time Limit: 12000/4000MS (Java/Ot ...

  6. swift新建类和子类方法的重写与重载

    1.首先什么是重写与重载? 一.重写(override) override是重写(覆盖)了一个方法,以实现不同的功能.一般是用于子类在继承父类时,重写(重新实现)父类中的方法. 重写(覆盖)的规则: ...

  7. require.js的用法(转)

    一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载.下面的网页代 ...

  8. php实现二分查找法

    二分查找法需要数组是一个有序的数组 假设我们的数组是一个递增的数组,首先我们需要找到数组的中间位置. 一.要知道中间位置就需要知道起始位置和结束位置,然后取出中间位置的值来和我们的值做对比. 二.如果 ...

  9. TF录像存储专项测试

    测试环境 移动设备:小米4C 移动设备版本:Android 5.1 IPC版本号:0.1.4110_10.1.1.1.3948 安居小宝版本:Version:2.0.1 测试网络:IPC使用WIFI网 ...

  10. 使用python进行汉语分词-乾颐堂

    目前我常常使用的分词有结巴分词.NLPIR分词等等 最近是在使用结巴分词,稍微做一下推荐,还是蛮好用的. 一.结巴分词简介 利用结巴分词进行中文分词,基本实现原理有三: 基于Trie树结构实现高效的词 ...