洛谷P4513 小白逛公园 (线段树)
这道题看起来像是线段树和最大子段和的结合,但这里求最大子段和不用dp,充分利用线段树递归的优势来处理。个人理解:线段树相当于把求整个区间的最大子段和的问题不断划分为很多个小问题,容易解决小问题,然后递归处理较大的问题(分治),所以这就可以用来解决。
在线段树中,除了左端点,右端点,新开4个域——ans,ml,mr,sum,其中sum为该区间的和,ans为该区间上的最大子段和,ml为必须包含左端点(以左端点为头)的最大子段和,mr为必须包含右端点(以右端点为尾)的最大子段和。
更新操作在up()中,应该容易看懂,需要思考的是查询操作,他返回的是一个结构体类型,该操作相当于针对某个询问的区间来更新结果,最后的query().ans也就是答案了
1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int N=5e5+10;
5 int n,m;
6 struct node{
7 int l,r;
8 ll ml,mr,sum,ans;
9 }t[N<<2];
10
11 void up(int k){
12 t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
13 t[k].ml=max(t[k<<1].ml,t[k<<1].sum+t[k<<1|1].ml);
14 t[k].mr=max(t[k<<1|1].mr,t[k<<1|1].sum+t[k<<1].mr);
15 t[k].ans=max(max(t[k<<1].ans,t[k<<1|1].ans),t[k<<1].mr+t[k<<1|1].ml);
16 }
17
18 void build(int k,int l,int r){
19 t[k].l=l,t[k].r=r;
20 if(l==r){
21 scanf("%lld",&t[k].sum);
22 t[k].ml=t[k].mr=t[k].ans=t[k].sum;
23 return ;
24 }
25 int mid=(l+r)>>1;
26 build(k<<1,l,mid);build(k<<1|1,mid+1,r);
27 up(k);
28 }
29
30 node query(int k,int l,int r){
31 if(t[k].l>=l && t[k].r<=r) return t[k];
32 int mid=(t[k].l+t[k].r)>>1;
33 if(r<=mid) return query(k<<1,l,r);
34 else if(l>mid) return query(k<<1|1,l,r);
35 else{
36 node t,a=query(k<<1,l,r),b=query(k<<1|1,l,r);
37 t.sum=a.sum+b.sum;
38 t.ml=max(a.ml,a.sum+b.ml);
39 t.mr=max(b.mr,b.sum+a.mr);
40 t.ans=max(max(a.ans,b.ans),a.mr+b.ml);//合并
41 return t;
42 }
43 }
44
45 void change(int k,int p,int x){//将p位置上的数改为x
46 if(t[k].l==t[k].r && t[k].l==p){
47 t[k].ml=t[k].mr=t[k].ans=t[k].sum=x;
48 return ;
49 }
50 int mid=(t[k].l+t[k].r)>>1;
51 if(p<=mid) change(k<<1,p,x);
52 else change(k<<1|1,p,x);
53 up(k);
54 }
55
56 int main(){
57 scanf("%d%d",&n,&m);
58 build(1,1,n);
59 while(m--){
60 int opt,a,b;
61 scanf("%d%d%d",&opt,&a,&b);
62 if(opt==1){
63 if(a>b) swap(a,b);
64 printf("%lld\n",query(1,a,b).ans);
65 }
66 else change(1,a,b);
67 }
68 }
洛谷P4513 小白逛公园 (线段树)的更多相关文章
- 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间合并(单点更新、区间查询)
P4513 小白逛公园 题目背景 小新经常陪小白去公园玩,也就是所谓的遛狗啦… 题目描述 在小新家附近有一条“公园路”,路的一边从南到北依次排着nn个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩 ...
- 2018.07.23 洛谷P4513 小白逛公园(线段树)
传送门 线段树常规操作了解一下. 单点修改维护区间最大连续和. 对于一个区间,维护区间从左端点开始的连续最大和,从右端点开始的连续最大和,整个区间最大和,区间和. 代码如下: #include< ...
- P4513 小白逛公园 (线段树)
题目链接 Solution 线段树是一门比较刁钻的手艺... 此题我们需要维护 \(4\) 个变量: \(amx\) 代表当前节点的最大值. \(lmx\) 代表当前节点以左端点为起点的区间最大值. ...
- 洛谷P4513 小白逛公园
区间最大子段和模板题.. 维护四个数组:prefix, suffix, sum, tree 假设当前访问节点为cur prefix[cur]=max(prefix[lson],sum[lson]+pr ...
- Bzoj 1756: Vijos1083 小白逛公园 线段树
1756: Vijos1083 小白逛公园 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1021 Solved: 326[Submit][Statu ...
- Vijos 1083 小白逛公园(线段树)
线段树,每个结点维护区间内的最大值M,和sum,最大前缀和lm,最大后缀和rm. 若要求区间为[a,b],则答案max(此区间M,左儿子M,右儿子M,左儿子rm+右儿子lm). ----------- ...
- [vijos]1083小白逛公园<线段树>
描述 小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了. 一开始,小白就根据公园的风景给每个公 ...
- [日常摸鱼]Vijos1083小白逛公园-线段树
题意:单点修改,询问区间最大子段和,$n\leq 5e5$ 考虑分治的方法$O(nlogn)$求一次最大子段和的做法,我们是根据中点分成左右两个区间,那么整个区间的答案要么是左边答案,要么是右边答案, ...
- 洛谷 P3373 【模板】线段树 2
洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...
随机推荐
- Golang 盲注脚本
Golang 盲注脚本 payload部分 其中脚本最重要的环节就是payload部分了,需要如何去闭合,如何构造SQL语句来达到判断的效果.(还有如何绕过waf等等...) bool盲注 下面是最基 ...
- Go语言基础二:常用的Go工具命令
常用的Go工具命令 Go附带了一下有用的命令,这些命令可以简化开发的过程.命令通常包含的IDE中,从而使工具在整个开发环境中保持一致. go run 命令 go run命令实在开发过程中执行的最常见的 ...
- 关于2022年3月9日之后Typora登录不了--已解决
p.s.今天是2022.7.27,软件版本:13.6.1 (以下所有方法,亲自尝试后整理出的) 报错信息: This beta version of typora is expired, please ...
- php apache 和mysql查看版本常用方法收集
php: 1.命令行查询,下图是因为添加php进系统环境变量了 2.预定义常量PHP_VERSION查询 3.phpversion()函数查询 4.phpinfo()查询 apache: mysql: ...
- 快速体验Spring Boot了解使用、运行和打包 | SpringBoot 2.7.2学习系列
SpringBoot 2.7.2 学习系列,本节内容快速体验Spring Boot,带大家了解它的基本使用.运行和打包. Spring Boot 基于 Spring 框架,底层离不开 IoC.AoP ...
- 6.14 YZBOI模拟赛solution
\(6.14\ YZBOI\)模拟赛\(solution\) 本来不想写题解来着...毕竟是自己找的题还是写一写吧 上午为了整活,就把赛制改成\(IOI\)赛制了,于是乎拯救了大家的\(70pts\) ...
- 清理忽略springboot控制台启动的banner和启动日志
清理忽略springboot控制台启动的banner和启动日志 1.springboot的banner spring: main: banner-mode: off 2.mybatis-plus的ba ...
- PHP 获取数组长度
count()函数,默认是获取一维数组,参数为:COUNT_NORMAL,添加第二个参数:COUNT_RECURSIVE,则可以获取多维关联数组的长度(意思为递归获取),例如:count($arr, ...
- Linux使用netstat查看网络状态
查看本机的网络状态.使用netstat查看网络状态.显示系统端口使用情况.UDP类型的端口.TCP类型的端口.只显示所有监听端口.只显示所有监听tcp端口. 命令使用举例 命令 说明 netstat ...
- Prometheus完整安装
官方组件: prometheus node_exporter blackbox_exporter alertmanager VictoriaMetrics 第三方开源软件: ConsulManager ...