
Can you answer these queries III (线段树维护最大子段和)
4.rmax同理: r m a x [ n o d e ] = m a x ( r m a x [ r s ] , s u m [ r s ] + r m a x [ l s ] ) ; rmax[node]=max(rmax[rs],sum[rs]+rmax[ls]); rmax[node]=max(rmax[rs],sum[rs]+rmax[ls]); 图略。
发布日期:2021-05-10 09:53:28
浏览次数:12
分类:精选文章
本文共 2392 字,大约阅读时间需要 7 分钟。
题意:
求一个区间的最大连续和。 0:表示把A[x]改成y 1:表示求[x,y]这个区间的最大连续和。题解:
线段树维护四个变量。 倒着讲,先来看如何维护这四个变量。 summax代表这个区间连续最大值,sum代表这个区间总和,lmax代表区间左端开始最大连序值,rmax代表区间右端开始最大连续值。1.summax:
题目要求要连续,所以summax由他下面两端区间计算得出: s u m m a x [ n o d e ] = m a x ( m a x ( s u m m a x [ l s ] , s u m m a x [ r s ] ) , l m a x [ r s ] + r m a x [ l s ] ) ; 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: l m a x [ n o d e ] = m a x ( l m a x [ l s ] , s u m [ l s ] + l m a x [ r s ] ) ; lmax[node]=max(lmax[ls],sum[ls]+lmax[rs]); lmax[node]=max(lmax[ls],sum[ls]+lmax[rs]); 可能有两种方法: (1).左孩子的lmax (2).左孩子全部+有孩子的lmax (也是node结点的lmax) 这两者取最大
对于query时,上面的所说的维护同时适用,同时返回四个参数计算,我们可以选择引用的方法进行传递。
代码:
/*Keep on going Never give up*///#pragma GCC optimize(3,"Ofast","inline")#include//#include //#include //#include //#include //#include #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 >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< <
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2025年04月22日 13时49分33秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
IDEA上传Jar
2021-05-10
SpringBoot工程临时加一个分页的yml文件没有生效
2021-05-10
搭建的SpringMVC项目,404错误,确保代码正确的前提,可能是jar包没导进去
2021-05-10
flume使用中的一些常见错误解决办法 (地址已经使用)
2021-05-10
基于递归的全排列
2021-05-10
前端笔试题总结(三) - CSS篇
2021-05-10
C语言字符型、整型和变量的长度
2021-05-10
OpenCV camshift目标追踪
2021-05-10
Redis缓存穿透和缓存雪崩
2021-05-10
spring 的@ComponentScan 理解
2021-05-10
C++ e 神秘数组——vector
2021-05-10
day04_CSS选择器
2021-05-10
js 获取时间戳的方法
2021-05-10
C++ 底层语言的信仰-指针分类
2021-05-10
DFS
2021-05-10
概念模型向逻辑模型的转换
2021-05-10
python基础语法
2021-05-10
const修饰指针(常量指针与指针常量的区别)
2021-05-10