题意:单点修改,询问区间最大子段和,$n\leq 5e5$


考虑分治的方法$O(nlogn)$求一次最大子段和的做法,我们是根据中点分成左右两个区间,那么整个区间的答案要么是左边答案,要么是右边答案,要么是左边的最大后缀和加上右边的最大前缀和。而一个区间的最大前缀和又会等于它左区间的最大前缀和或者是左区间的和加上右区间最大前缀和。

基于这种思想我们就有了一种动态求最大字段和的算法了,区间和,前缀后缀和,都可以直接用线段树维护,用这些信息就能求出最大子段和了。

注意询问的时候应该把整个结点的信息储存下来,因为我们要查询的是一个区间而不是一整段,如果直接返回结点的答案话可能会把询问区间外面的信息也算进来。

#include<cstdio>
typedef long long lint;
const int N=500005;
inline lint read()
{
lint s=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){s=s*10+c-'0';c=getchar();}
return s*f;
}
struct node
{
lint ls,rs,key,s;
node(lint a=0,lint b=0,lint c=0,lint d=0):ls(a),rs(b),key(c),s(d){}
};
int n,m;
lint ls[N<<2],rs[N<<2],key[N<<2],s[N<<2],v[N]; inline void swap(int &a,int &b){int t=a;a=b;b=t;}
inline lint max(lint a,lint b){return a>b?a:b;}
#define lson (o<<1)
#define rson (o<<1|1)
inline void push_up(int o)
{
ls[o]=max(ls[lson],s[lson]+ls[rson]);
rs[o]=max(rs[rson],s[rson]+rs[lson]);
s[o]=s[lson]+s[rson];
key[o]=max(max(key[lson],key[rson]),rs[lson]+ls[rson]);
}
inline void build(int o,int l,int r)
{
if(l==r)
{
ls[o]=rs[o]=key[o]=s[o]=v[l];
return;
}int mid=(l+r)>>1;
build(lson,l,mid);build(rson,mid+1,r);
push_up(o);
}
inline void modify(int o,int l,int r,int q,lint val)
{
if(l==r)
{
ls[o]=rs[o]=key[o]=s[o]=val;
return;
}
int mid=(l+r)>>1;
if(mid>=q)modify(lson,l,mid,q,val);
else modify(rson,mid+1,r,q,val);
push_up(o);
}
inline node query(int o,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)return node(ls[o],rs[o],key[o],s[o]);
int mid=(l+r)>>1,op=0;node L,R,ans;
if(mid>=ql)L=query(lson,l,mid,ql,qr),op++;
if(mid+1<=qr)R=query(rson,mid+1,r,ql,qr),op+=2;
if(op==1)return L;if(op==2)return R;
ans.ls=max(L.ls,L.s+R.ls);ans.rs=max(R.rs,R.s+L.rs);
ans.s=L.s+R.s;ans.key=max(max(L.key,R.key),L.rs+R.ls);
return ans;
} #undef lson
#undef rson int main()
{
n=read();m=read();
for(register int i=1;i<=n;i++)v[i]=read();
build(1,1,n);
while(m--)
{
int op,a,b;op=read();
if(op==1)
{
a=read();b=read();if(a>b)swap(a,b);
printf("%lld\n",query(1,1,n,a,b).key);
}else
{
a=read();b=read();
modify(1,1,n,a,b);
}
}
}

[日常摸鱼]Vijos1083小白逛公园-线段树的更多相关文章

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

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

  2. Vijos 1083 小白逛公园(线段树)

    线段树,每个结点维护区间内的最大值M,和sum,最大前缀和lm,最大后缀和rm. 若要求区间为[a,b],则答案max(此区间M,左儿子M,右儿子M,左儿子rm+右儿子lm). ----------- ...

  3. [vijos]1083小白逛公园<线段树>

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

  4. P4513 小白逛公园 (线段树)

    题目链接 Solution 线段树是一门比较刁钻的手艺... 此题我们需要维护 \(4\) 个变量: \(amx\) 代表当前节点的最大值. \(lmx\) 代表当前节点以左端点为起点的区间最大值. ...

  5. BZOJ 1756: Vijos1083 小白逛公园

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

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

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

  7. 【线段树】bzoj1756 Vijos1083 小白逛公园

    我们知道,求一段序列的最大子段和是O(n)的,但是这样是显然会超时的. 我们需要一个数据结构来支持修改和计算的操作,对于这种修改一个而查询区间的问题,考虑使用线段树. 在线段树中,除了左端点,右端点, ...

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

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

  9. bzoj1756 Vijos1083 小白逛公园

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

随机推荐

  1. java开发两年了,连个java代理模式都摸不透,你怎么跳槽涨薪?

    前言 代理模式(Proxy Pattern),23种java常用设计模式之一.代理模式的定义:代理类对被代理对象提供一种代理以控制对这个对象的访问.代理类主要负责为委托类预处理消息.过滤消息.把消息转 ...

  2. 了解 MySQL的数据行、行溢出机制吗?

    目录 一.行 有哪些格式? 二.紧凑的行格式长啥样? 三.MySQL单行能存多大体量的数据? 四.Compact格式是如何做到紧凑的? 五.什么是行溢出? 六.行 如何溢出? 七.思考一个问题 关注送 ...

  3. jQuery 第八章 实例方法 遍历索引

    遍历索引相关方法: .each() .index() ------------------------------------------------- .each() 有点像数组的 forEach( ...

  4. AFNetWorking 丢失数据

    问题描述: 使用AFNetWorking请求数据,请求成功,但是拿不到所需要的数据,但是使用其他平台都可以拿到数据. 原因分析: AFNetWorking无法解析. 解决方式: AFJSONRespo ...

  5. Java基础教程——序列化

    序列化 序列化:Serialize,将Java对象写入IO流(可以保存在数据库,文件等) 反序列化:Deserialize,从IO流中读取并恢复Java对象. 这么理解:序列化就是把对象封印起来,反序 ...

  6. jvm系列(一)运行时数据区

    C++程序员肩负着每一个对象生命周期开始到终结的维护责任.Java程序员则可以借助自动内存管理机制,不需要自己手动去释放内存.由虚拟机进行内存管理,不容易出现内存泄漏和内存溢出的问题,但是一旦出现这些 ...

  7. C语言printf()函数的格式化字符串

    原文链接:https://www.runoob.com/cprogramming/c-function-printf.html#include<stdio.h> #include<s ...

  8. IdentityServer4系列 | 快速搭建简易项目

    一 .前言 从上一篇关于 常见术语说明中,主要是对IdentityServer4的说明,以及其中涉及常见的术语的表述说明,包括对身份认证服务器.用户.客户端.资源以及各个令牌等进行对比区别说明. 而在 ...

  9. CAS学习过程中的一些记录

    1 inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { 2 int ...

  10. 老猿学5G专栏完结说明

    老猿学5G是因为工作原因促成的,主要目的是为了研究5G的计费架构相关内容,到今天为止,基本上达成目标,因此这个专栏基本上告一段落了. 回想这2个多月的日子,从一个对5G相关知识完全不熟悉的小白,到现在 ...