我们知道,求一段序列的最大子段和是O(n)的,但是这样是显然会超时的。

我们需要一个数据结构来支持修改和计算的操作,对于这种修改一个而查询区间的问题,考虑使用线段树。

在线段树中,除了左端点,右端点,左儿子指针,右儿子指针之外,新开4个域——max,maxl,maxr,sum,其中sum为该区间的和,max为该区间上的最大子段和,maxl为必须包含左端点的最大子段和,maxr为必须包含右端点的最大子段和。

然后就……可以用线段树来统计了,注意求得的最大子段和中至少包含1个元素,所以出现了样例那样的输出负值。

修改时:

1、若左儿子的maxr和右儿子的maxl都为负,就从中取较大的为该节点的max(防止一个都不取),反之取二者中正的(都正就都取)。

2、将该节点的max用左右儿子的max更新。

3、该节点的maxl为左儿子的maxl与左儿子sum和右儿子maxl和的最大值。

4、该节点的maxr为右儿子的maxr与右儿子sum和左儿子maxr和的最大值。

5、该节点的sum为左右儿子的sum和。

查询时:

1、如果查询区间覆盖这一节点,将该节点信息返回。

2、如果只与一个儿子有交集,就返回在那个儿子中查找到的信息。

3、如果与两个儿子都有交集,就先分别计算出两个儿子的信息,然后按修改的方式将两个信息合并,然后返回。

4、最后返回的max值即为答案。

——http://www.cnblogs.com/whitecloth/archive/2012/03/22/2410925.html

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 500001
struct Node{int maxv,maxl,maxr,sumv;}T[N<<2];
inline void pushup(Node &rt,const Node &ls,const Node &rs)
{
if(ls.maxr<0 && rs.maxl<0)
rt.maxv=max(ls.maxr,rs.maxl);
else
{
rt.maxv=0;
if(ls.maxr>0)
rt.maxv+=ls.maxr;
if(rs.maxl>0)
rt.maxv+=rs.maxl;
}
rt.maxv=max(rt.maxv,ls.maxv);
rt.maxv=max(rt.maxv,rs.maxv);
rt.maxl=max(ls.maxl,ls.sumv+rs.maxl);
rt.maxr=max(rs.maxr,rs.sumv+ls.maxr);
rt.sumv=ls.sumv+rs.sumv;
}
void buildtree(int rt,int l,int r)
{
if(l==r)
{
scanf("%d",&T[rt].maxv);
T[rt].sumv=T[rt].maxl=T[rt].maxr=T[rt].maxv;
return;
}
int m=(l+r>>1);
buildtree(rt<<1,l,m);
buildtree(rt<<1|1,m+1,r);
pushup(T[rt],T[rt<<1],T[rt<<1|1]);
}
void update(int p,int v,int rt,int l,int r)
{
if(l==r)
{
T[rt].sumv=T[rt].maxl=T[rt].maxr=T[rt].maxv=v;
return;
}
int m=(l+r>>1);
if(p<=m) update(p,v,rt<<1,l,m);
else update(p,v,rt<<1|1,m+1,r);
pushup(T[rt],T[rt<<1],T[rt<<1|1]);
}
Node query(int ql,int qr,int rt,int l,int r)
{
if(ql<=l&&r<=qr) return T[rt];
int m=(l+r>>1);
if(ql<=m && m<qr)
{
Node res;
pushup(res,query(ql,qr,rt<<1,l,m),query(ql,qr,rt<<1|1,m+1,r));
return res;
}
else if(ql<=m) return query(ql,qr,rt<<1,l,m);
else return query(ql,qr,rt<<1|1,m+1,r);
}
int n,m;
int main()
{
int op,x,y;
scanf("%d%d",&n,&m);
buildtree(1,1,n);
for(;m;--m)
{
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
if(x>y)
swap(x,y);
printf("%d\n",query(x,y,1,1,n).maxv);
}
else update(x,y,1,1,n);
}
return 0;
}

【线段树】bzoj1756 Vijos1083 小白逛公园的更多相关文章

  1. 线段树 || BZOJ1756: Vijos1083 小白逛公园 || P4513 小白逛公园

    题面:小白逛公园 题解: 对于线段树的每个节点除了普通线段树该维护的东西以外,额外维护lsum(与左端点相连的最大连续区间和).rsum(同理)和sum……就行了 代码: #include<cs ...

  2. bzoj1756 Vijos1083 小白逛公园

    Description 小新经常陪小白去公园玩,也就是所谓的遛狗啦-在小新家附近有一条"公园路",路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了. ...

  3. Bzoj 1756: Vijos1083 小白逛公园 线段树

    1756: Vijos1083 小白逛公园 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1021  Solved: 326[Submit][Statu ...

  4. BZOJ 1756: Vijos1083 小白逛公园

    题目 1756: Vijos1083 小白逛公园 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 856  Solved: 264[Submit][Sta ...

  5. 【Vijos1083/BZOJ1756】小白逛公园(线段树)

    [写在前面]TYC (Little White) 真是太巨啦! 题目: Vijos1083 分析: 一眼看上去就是线段树啊-- 然而当我这种蒟蒻兴高采烈地把线段树模板敲了一半,却发现一个问题: 这子区 ...

  6. 【BZOJ】1756: Vijos1083 小白逛公园(线段树)

    题目 传送门:QWQ 分析 线段树维护一下最大子序列 维护一下最大前缀 最大后缀  区间和 就ok了 好像只能用结构体..... 代码 #include <bits/stdc++.h> u ...

  7. [日常摸鱼]Vijos1083小白逛公园-线段树

    题意:单点修改,询问区间最大子段和,$n\leq 5e5$ 考虑分治的方法$O(nlogn)$求一次最大子段和的做法,我们是根据中点分成左右两个区间,那么整个区间的答案要么是左边答案,要么是右边答案, ...

  8. 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间合并(单点更新、区间查询)

    P4513 小白逛公园 题目背景 小新经常陪小白去公园玩,也就是所谓的遛狗啦… 题目描述 在小新家附近有一条“公园路”,路的一边从南到北依次排着nn个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩 ...

  9. vijos1083:小白逛公园

    小白逛公园 描述 小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了. 一开始,小白就根据公园的 ...

随机推荐

  1. 9png图片制作

    制作步骤不多说了,这儿有链接:http://blog.csdn.net/pugongying1988/article/details/6938972 链接中去边框一个像素可以不用做,直接用androi ...

  2. 第十章 DOM

    10.1节点层次 html元素通过元素节点表示,特性节点通过特性节点表示,文档类型节点通过文档类型节点访问,这些类型都继承一个基类型. 10.1.1 Node类型 JavaScript中的所有节点类型 ...

  3. python学习文章

    推荐大家看看,这几个涉及到解决问题了 用机器学习算法解决问题(图文+程序) http://www.bida.org.cn/index.php?qa=7 数据的价值是提升业务而不仅仅是用户画像 http ...

  4. 深入理解js——自由变量和作用域链

    自由变量:在A作用域中使用变量X,却没有在A作用域中声明(在其他作用域中声明),对于A作用域来说X就是一个自由变量. var x=10; function fn(){ var b=20; consol ...

  5. [译]ABP框架使用AngularJs,ASP.NET MVC,Web API和EntityFramework构建N层架构的SPA应用程序

    本文转自:http://www.skcode.cn/archives/281 本文演示ABP框架如何使用AngularJs,ASP.NET MVC,Web API 和EntityFramework构建 ...

  6. SOCKS 5协议详解(转)

    笔者在实际学习中,由于在有些软件用到了socks5(如oicq,icq等),对其原理不甚了解,相信很多朋友对其也不是很了解,于是仔细研读了一下rfc1928,觉得有必要译出来供大家参考. 1.介绍: ...

  7. as3自定义事件

    package EventPackage { import flash.events.Event; /** * * @author tqr <br /> * 创建时间:2015-2-6 下 ...

  8. android中的requestFocus标签

    <requestFocus />标签用于指定屏幕中的焦点View 用法:置于Views标签内部 ex: <EditText             android:id=" ...

  9. PHP获取具有相同name的多个input表单信息

    首先是表单应该这样写,注意每个 name="name[]"后面是有一个方括号的.这是PHP特有的获取具有相同name的多个input元素value的方法.(复选框也是采用这种方法) ...

  10. Python Decorator分析

    decorator本身是一个函数,这个函数的功能是接受被修饰的函数(decorated)作为参数,返回包装函数(wrapper)替换被修饰函数(decorated). @decorator func ...