[HNOI2002]营业额统计
题目大意:给你一串n数序列,对于每一个刚输入的数a,找到一个前面的数k,使得|a-k|最小。
注释:$n<=32767,ai<=10^6$。
想法:刚学Treap。这道算Treap的练习题里吧,对于新手来讲还是挺有意义的。首先,我们先来讲一讲Treap是个什么东西。
Treap,是二叉搜索树(Tree)和堆(Heap)的合体,读音也是这两个东西捏在一起的(懵-)。我们来看一下这东西是怎么实现的。
Treap是一种二叉搜索树,但也是一种平衡树。我们显然知道,对于二叉搜索树来讲,如果插入的顺序是直接升序或者降序,二叉搜索树就会退化成一条链,查找和修改还有删除的时间复杂度都会从原本的期望logn滚粗会O(n)。这就很蛋疼,而且卡二叉搜索树的题有不少,那么我们可以用一种什么样的办法来使得二叉搜索树趋近于平衡的呢?这是一个问题。然后我们再来看另一个问题。
关于Heap来讲,升序或者降序对于堆的伤害显然是... ...没有的。我们尝试用Heap将二叉搜索树进行一定的改造。之前的二叉搜索树的节点维护的只是权值,现在,我们让它在多一个随机的rand。这样的好处是什么?就是可以用这个随机的rand来使得存在一个树,满足这个树对于原本二叉搜索树的权值来讲是满足二叉搜索树的,对于rand来讲是满足heap的(这里是大根堆还是小根堆是无所谓的)。如何来呈现一颗这样的树呢?我们通过旋转Treap的核心操作——旋转。如何进行旋转?