线段树与其他数据结构的组合
例题: 百度之星2008 初赛 第一天第三题 钉子与木板
题目描述:
墙上有n个钉子,编号为1, 2, …, n。其中钉子i的横坐标为i,纵坐标初始
为xi。可以进行两种操作:
0 k v:竖直移动钉子k,坐标变为(k, v)。
1 s t v:若在高度为v处放一块横坐标范围是[s,t]的水平木板,它将下落到
什么高度?换句话说,求出钉子s, s+1, s+2, …, t的纵坐标中,不超过v的最大
值。如果这些钉子的高度全部大于v,则木板将落到地上,高度为0。
题目分析:
题目中的每个询问要求一个区间中,不超过v的最大值。由于每次询问的v
值不同,我们无法在线段树的节点中记录不超过v的最大值。这时,我们可以在
每个节点中另外使用一个新的数据结构——平衡树,平衡树可以在O(logn)的时
间内查找一个具体数值,并计算树中比这个数值小的数的个数。具体思路如下,
将每个节点的区间中的所有点建立平衡树,当有修改操作的时候,对根节点到叶
节点路径上的所有节点中的平衡树进行修改。查询时,只需按一般方法递归查询
即可。
这道题说明了线段树的节点中不仅可以存放单一的信息,还可以存放其他数
据结构,做到线段树与其他数据结构的组合,使得功能更为强大,解题也更加灵
活。
在每个节点建立平衡树,更新值的时候每个树都要更新有点复杂吧。
不能像找在[a,b]区间第k个数一样一开始就用merge sort排序好。
找到可能需要插入位置,后面就复制吧?
就和插入排序类似?