在平衡树中,经常会让我们查一下一个值的前驱或后继是谁,写两个函数就非常麻烦好吧,所以这里咱们用一点小技巧来让他变
成一个函数(这里的前驱后继定义时包括与本身相等的值)
代码
点击查看代码
int nxt(int k){if(!m[rt].size) return 0;int root=rt;while(k!=m[root].val&&m[root].ch[k>m[root].val])root=m[root].ch[k>m[root].val];splay(root);return root?m[root].val:m[rt].val;}
原理解析
这个代码本质是在查后继,但如果我们想再查前驱怎么办,只要再调用一次就好了,就像下面的操作一样
这里的 \(temp\) 是后继,\(mp\) 是前驱。
这实际上全是代码中 \(splay\) 的功劳,我们先将第一个大于等于 \(k\) 的值转到根,那么下一次第一次跳时肯定会往左子树
去跳,而左子树没有比 \(k\) 大的,所以只需要在其中找最大的那个值就是第一个小于等于 \(k\) 的值