Problem
一个长度为n的序列,支持一堆操作,大致操作如下:
1.k在区间的排名(由小到大)2.区间第k小;3.单点修改;4&5:k的在区间上的前驱/后继。
Solution
右边大佬说树套树很简单,就是两个基本操作套起来即可。
然后我码了一个半小时才码完。
虽然话没说错,树状数组套主席树……
但是这代码……
算了,还是太菜了……
2,3操作:
其实做法比较好理解,树状数组具有前缀性,主席树也是利用前缀
所以可以将树状数组的每一个节点上建一颗主席树
这样就可以完美的实现修改操作了
具体实现……就是把原本的树状数组一般操作改为主席树上的修改操作
询问的时候将树状数组上$lowbit$到的点全部带进去主席树里去询问就可以了。
以上是第2,3操作(搞了半天才完成2,3操作)
1操作:
考虑线段树的遍历过程
如果当前权值线段树的$mid$大于当前询问的权值k,那么我们会走向左儿子,否则往走向右儿子
而且,当我们走向右儿子时k一定大于左边的所有数
所以我们只要在此时加左子树的数的个数即可
4,5操作:
既然知道了任意数在区间里的$rank$前驱和后继就很好处理了
$k$前驱只需要查$k$在区间里的$rank$,区间排名为$rank - 1$的数即为所求
$k$的后继则需要知道$k$在区间中的$rank$与$k$在区间中出现的次数$num$,再求区间中排名为$rank+num$的数即可。
放一份奇丑的代码,以后再改。
Code
1 |
|