[学习笔记]线段树骚操作选讲

引入

  • 众所周知,线段树可以维护序列,进行区间操作
  • 单点加 + 区间求和
  • 区间加 + 区间求和
  • 区间加 + 区间乘 + 区间求和
  • (省略 + ∞ +\infty + 行)
  • 但有些操作不能像上面三个问题一样通过简单的打标记 + 提取区间解决
  • 而需要用到一些 trick

一、势能线段树

  • 我们知道,线段树能够通过打标记实现区间修改的条件有两个:
  • (1)能够快速处理标记对区间询问结果的影响
  • (2)能够快速实现标记的合并
  • 但有的区间修改不满足上面两个条件
  • 但某些修改存在一些奇妙的性质,使得序列每个元素被修改的次数有一个上限
  • 可以在线段树每个节点上记录一个值,表示对应区间内是否每个元素都达到修改次数上限
  • 区间修改时暴力递归到叶子节点,如果途中遇到一个节点,这个节点的对应区间内每个元素都达到修改次数上限则在这个节点 return 掉
  • 可以证明复杂度为 O ( n log ⁡ n × 修 改 次 数 上 限 ) O(n\log n\times修改次数上限) O(nlogn×)
  • 用几个简单的栗子说明一下

一、区间开平方,区间求和

  • 一个数 x x x 被开平方 O ( log ⁡ log ⁡ x ) O(\log\log x) O(loglogx) 后会变成 1 1 1 0 0 0 ,继续开根后不变
  • 所以线段树节点上用一个变量记录是否区间内全为 1 1 1 0 0 0
  • 修改时递归到叶子,如果到达了区间内全为 1 1 1 0 0 0 的节点则 return 掉
  • 复杂度 O ( n log ⁡ n log ⁡ log ⁡ x ) O(n\log n\log\log x) O(nlognloglogx)

二、区间取模,区间求和

  • 一个数 x x x p p p 取模,如果 x ≥ p x\ge p xp x x x 至少变小一半
  • 每个节点维护区间和以及区间最小值
  • 区间对 p p p 取模时仍然递归到叶子
  • 如果某节点的区间最小值小于 p p p 则 return 掉
  • 复杂度 O ( n log ⁡ n log ⁡ x ) O(n\log n\log x) O(nlognlogx)

三、区间除(下取整),区间加,区间求和

  • 区间整除 1 1 1 是无效的,直接跳过
  • 否则整除一个数会使区间内最大值与最小值的差至少减小一半
  • 维护区间最小值和最大值以及区间和,区间加标记
  • 整除时递归到叶子
  • 如果最小值和最大值的差为 0 0 0 ,则该区间内所有数都相等
  • 直接打上标记,注意这时候标记可以处理对区间和的影响
  • 复杂度 O ( n log ⁡ n log ⁡ x ) O(n\log n\log x) O(nlognlogx)

二、李超树 / 李超线段树 / 超哥线段树

  • 考虑经典问题
  • 维护一个二维平面
  • 支持横坐标 [ l , r ] [l,r] [l,r] 范围内插入一条线段,查询某个横坐标上的最高点
  • 换成人话,区间对一个等差数列取 max ⁡ \max max ,单点查值
  • 线段树每个节点维护一个标记(一条线段)
  • 仍然把 [ l , r ] [l,r] [l,r] 拆成线段树上不超过 O ( log ⁡ n ) O(\log n) O(logn) 个区间
  • 我们要处理的关键问题是标记的合并,也就是两条线段 l 1 l_1 l1 l
  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值