Can you answer these queries III (线段树维护最大子段和)
题意:
求一个区间的最大连续和。
0:表示把A[x]改成y
1:表示求[x,y]这个区间的最大连续和。
题解:
线段树维护四个变量。
倒着讲,先来看如何维护这四个变量。
summax代表这个区间连续最大值,sum代表这个区间总和,lmax代表区间左端开始最大连序值,rmax代表区间右端开始最大连续值。
1.summax:
题目要求要连续,所以summax由他下面两端区间计算得出:
summax[node]=max(max(summax[ls],summax[rs]),lmax[rs]+rmax[ls]);summax[node]=max(max(summax[ls],summax[rs]),lmax[rs]+rmax[ls]);summax[node]=max(max(summax[ls],summax[rs]),lmax[rs]+rmax[ls]);
也就是 左孩子的区间最大、有孩子的区间最大、(左孩子的rmax+有孩子的lmax)这三个值得最大组成。
2.sum不必多说,线段树模板。
3.lmax:
lmax[node]=max(lmax[ls],sum[ls]+lmax[rs]);lmax[node]=max(lmax[ls],sum[ls]+lmax[rs]);lmax[node]=max(lmax[ls],sum[ls]+lmax[rs]);
可能有两种方法:
(1).左孩子的lmax
(2).左孩子全部+有孩子的lmax (也是node结点的lmax)
这两者取最大
4.rmax同理:
rmax[node]=max(rmax[rs],sum[rs]+rmax[ls]);rmax[node]=max(rmax[rs],sum[rs]+rmax[ls]);rmax[node]=max(rmax[rs],sum[rs]+rmax[ls]);
图略。
对于query时,上面的所说的维护同时适用,同时返回四个参数计算,我们可以选择引用的方法进行传递。
代码:
/*Keep on going Never give up*/
//#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
//#include<iostream>
//#include<string>
//#include<cmath>
//#include<vector>
//#include<algorithm>
#define int long long
#define ls 2*node
#define rs 2*node+1
#define endl '\n'using namespace std;
const int maxn=4e5+10;
const int mod=1e9+7;
int a[maxn];
int sum[maxn],lmax[maxn],rmax[maxn],summax[maxn];void pushup(int node){summax[node]=max(max(summax[ls],summax[rs]),lmax[rs]+rmax[ls]);lmax[node]=max(lmax[ls],sum[ls]+lmax[rs]);rmax[node]=max(rmax[rs],sum[rs]+rmax[ls]);sum[node]=sum[ls]+sum[rs];
}void build(int node,int start,int ends){if(start==ends){summax[node]=sum[node]=lmax[node]=rmax[node]=a[start];return ;}int mid=(start+ends)/2;build(ls,start,mid);build(rs,mid+1,ends);pushup(node);
}
void query(int node,int start,int ends,int l,int r,int &Smax,int &Lmax,int &Rmax,int &Sum){if(l<=start&&ends<=r){Smax=summax[node];Lmax=lmax[node];Rmax=rmax[node];Sum=sum[node];return ;}int mid=(start+ends)/2;int smaxl=-1e9,lmaxl=-1e9,rmaxl=-1e9,suml=0;int smaxr=-1e9,lmaxr=-1e9,rmaxr=-1e9,sumr=0;if(l<=mid) query(ls,start,mid,l,r,smaxl,lmaxl,rmaxl,suml);if(mid<r) query(rs,mid+1,ends,l,r,smaxr,lmaxr,rmaxr,sumr);Lmax=max(lmaxl,suml+lmaxr);Rmax=max(rmaxr,sumr+rmaxl);Smax=max(max(smaxl,smaxr),rmaxl+lmaxr);Sum=suml+sumr;
}void update(int node,int start,int ends,int pos,int val){if(start==ends){summax[node]=sum[node]=lmax[node]=rmax[node]=val;return ;}int mid=(start+ends)/2;if(pos<=mid) update(ls,start,mid,pos,val);else update(rs,mid+1,ends,pos,val);pushup(node);
}signed main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n;cin>>n;for(int i=1;i<=n;i++) cin>>a[i];int q;cin>>q;build(1,1,n);while(q--){int l,r;int opt;cin>>opt;if(!opt){cin>>l>>r;update(1,1,n,l,r);}else{cin>>l>>r;int ans,xx,yy,zz;query(1,1,n,l,r,ans,xx,yy,zz);cout<<ans<<endl;}}}
Can you answer these queries III (线段树维护最大子段和)相关推荐
- SPOJ - GSS3 Can you answer these queries III(线段树+区间合并)
题目链接:点击查看 题目大意:给出一个长度为n的序列,进行m次操作: 1 x y 查询区间[l,r]中的最大连续子段和 0 x y 将第x个数修改为y 题目分析:因为涉及到单点修改和区间查询等操作 ...
- SPOJ GSS2 Can you answer these queries II (线段树离线) - xgtao -
Can you answer these queries II 这是一道线段树的题目,维护历史版本,给出N(<=100000)个数字(-100000<=x<=100000),要求求出 ...
- HDU 4027 Can you answer these queries?(线段树/区间不等更新)
传送门 Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/6576 ...
- [HDOJ4027]Can you answer these queries?(线段树,特殊成段更新,成段查询)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 RT,该题要求每次更新是更新所有节点,分别求平方根,查询是求和.昨晚思前想后找有没有一个数学上的 ...
- spoj 2916. Can you answer these queries V(线段树)
题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出n个数,求区间最大子段和,但是限制了子段的起点终点,起点要在[x1,y1]内,终点要在[x2,y2]内. 思路 ...
- [SDOI2011]染色 (线段树维护子段问题+树剖)
题意: 给定一棵 n 个节点的无根树,共有 m 个操作,操作分为两种: 1.将节点 a 到节点 b 的路径上的所有点(包括 a 和 b)都染成颜色 c. 2.询问节点 a 到节点 b 的路径上的颜色段 ...
- Can you answer these queries V SPOJ - GSS5 (分类讨论+线段树维护区间最大子段和)
recursion有一个整数序列a[n].现在recursion有m次询问,每次她想知道Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 &l ...
- 线性代数四之动态DP(广义矩阵加速)——Can you answer these queries III,保卫王国
动态DP--广义矩阵加速 SP1716 GSS3 - Can you answer these queries III description solution code [NOIP2018 提高组] ...
- 线段树维护(最大区间和,最大子段和,最长连续上升子序列)
本文主要介绍用线段树来维护(最大区间和,最大子段和,最长连续上升子序列)的问题. HDU 1540 Tunnel Warfare(最长连续区间+单点修改) 洛谷 P2894 [USACO08FEB]酒 ...
最新文章
- Android startActivityForResult
- 1.将cocos2d-x项目移植到Linux环境下,将cocos2d-x项目移植到手机上
- 第二阶段冲刺 站立会议03
- VIJOS 1052贾老二算算术 (高斯消元)
- spring cloud feign 上传文件报not a type supported by this encoder解决方案
- 【逻辑与计算理论】Lambda 演算——开篇
- Java对象初始化详解
- 数据算法之折半查找(binSearch)的Java实现
- Blue Prism如何成为RPA领域魔力象限领袖
- C++内嵌汇编 教程1
- 常用HTML5开发工具有哪些?
- 新美域杂志新美域杂志社新美域编辑部2022年第6期目录
- 微信小程序中进行地图导航
- 面试官问你为什么选择做客服_在线客户服务-您的选择
- 基于lora模块智能井盖解决方案
- 北京金普蝶:让客户满意就是最好的营销!
- 028. 考古学家[200 分]
- 基于JavaWeb实现的城市公交查询系统
- 7月26日 MySql单表查询作业
- java+磁盘io监控_磁盘IO利用率监控VBS脚本(windows)
热门文章
- Linux之查看命令帮助 --help man
- 爬虫之数据提取jsonpath模块的使用场景和使用方法
- 有必要总结一下:matlab图像灰度调整——imadjust函数的使用
- Python RE库的贪婪匹配和最小匹配
- CENTOS 7 nginx-1.6.2 下载 解压 安装
- 任意多相机系统的SLAM重设计
- 猫哥教你写爬虫 046--协程-实践-吃什么不会胖
- (原創) 如何將編譯結果,統一放在一個目錄下? (SOC) (Quartus II)
- 媒体行业注册什么企业邮箱比较好?
- 网站优化基础教程:发布外链常见的五种方式!