【luogu P6242】【模板】线段树 3(吉司机线段树)

这篇博客详细介绍了如何使用吉司机线段树解决区间操作问题,包括区间加值、取最小值、求和、求最大值及历史最大值的最大值。文章通过luogu P6242题目为例,解析了线段树节点的维护方式,如最大值、第二大值、区间和等,并阐述了懒惰标记的传播策略。

【模板】线段树 3

题目链接:luogu P6242

题目大意

给你一个数组,然后要你维护一些东西:
区间加值,区间取最小值,区间求和,区间求最大值,区间求每个位置的历史最大值的最大值。

思路

这题的难点在于你操作二取最小值是无法用普通的线段树维护区间和的。

所以就要用到吉司机线段树。
它主要是通过维护第一大和第二大这两个东西,如果大于等于第一个就肯定无法更新,如果大于第二个就只会更新第一大,就弄就好了,否则就递归下去更新。


然后开始讲如何维护:

l s x , r s x ls_x,rs_x lsx,rsx:左右儿子
s u m x sum_x sumx:区间权值和
m a x a x maxa_x maxax:区间最大数
s e c x sec_x secx:区间第二大数
c n t x cnt_x cntx:区间最大数的个数
m a x b x maxb_x maxbx:区间历史最大数
a d d _ a x add\_a_x add_ax:区间最大值的加法的懒标记
a d d _ a 1 x add\_a1_x add_a1x:区间的不是最大值的加法的懒标记(因为你要么递归下去搞,要么就搞最大值,所以可以这么维护)
a d d _ b x , a d d _ b 1 x add\_b_x,add\_b1_x add_bx,add_b1x:同理,不过这个是历史最大值和历史非最大值的懒标记。

然后你考虑怎么维护:

首先是上传: m a x a , m a x b maxa,maxb maxa,maxb 直接取最大值, s u m sum sum 直接加起来, s e c , c n t sec,cnt sec,cnt 稍微复杂一点就分类讨论一下即可。
然后是下传:考虑那边是最大值就把下传的最大给它的最大,否则它的最大是这个的非最大(两边的非最大自然都是非最大)
至于怎么给,就是这个线段树的一个难点了。

首先全部加上最大加的乘最大的个数和非最大加的和非最大的个数(非最大的个数用全部减去最大个数)。
然后历史最大要加的加上历史要加的,懒标记也要加上各自的,然后反正就是各自加各自的,具体可以看看这段代码:

void update(int now, int k1, int k2, int k3, int k4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值