区间k大——树套树

定义

  • 这里的树套树是用线段树套平衡树
  • 线段树用来维护区间位置信息,把这个区间中的所有数插进一颗平衡树中
  • 利用线段树信息可加的性质来维护区间k大

实现方法

问题

区间k大问题需要进行几个操作:

  1. 查询k在区间内的排名

  2. 查询区间内排名为k的值

  3. 修改某一位值上的数值

  4. 查询k在区间内的前驱 (前驱定义为严格小于x,且最大的数)

  5. 查询k在区间内的后继 (后继定义为严格大于x,且最小的数)

实现

  1. 查询区间内一个数的排名:在线段树上找到区间对应的节点,然后每个节点的平衡树内查询对应数的排名并求和。时间复杂度 O(log2N)O(\log^2N)
  2. 查询区间内排名为k的数是几:由于这项操作在线段树上不可加。所以我们考虑转换为判定一个数是不是区间内排名为k的。这个可以在 O(log2N)O(\log^2N)的时间内通过操作1完成。那么我们考虑二分答案,就可以解决这个问题。时间复杂度 O(log3N)O(\log^3N)
  3. 单点修改:我们在线段树上找到所有覆盖这个点的区间,然后在所有区间对应的平衡树中删除原数,加入新数即可。时间复杂度 O(log2N)O(log^2N)
  4. 对于4和5、 查询区间内一个数前驱、后继:这是平衡树上的经典问题。我们只需要对于所有区间分别查询,然后答案相应的取maxmin\max\min即可。时间复杂度 O(log2N)O(\log^2N)
    当然,由于序列中的一个数最多被插入 O(logN)O(\log N)个平衡树内,考虑到每次修改操作最多增加并删除一个节点,所以空间复杂度为 O(NlogN)O(N\log N) 。经过我们的分析,时间复杂度为 O(Nlog3N)(N\log^3N)。当然这是一个较松的上界。

代码

include<iostream>
发布了27 篇原创文章 · 获赞 5 · 访问量 1809
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览