废话
这也是个咕了很久才学的算法,现在快省选了再不学就来不及了……
然而模板并没有想象中的难,短短两三行就能写完,但是应用起来就很难了。
正题
笛卡尔树的每个节点有两个属性: 和 。对于第一个属性,笛卡尔树满足二叉搜索树的性质,对于第二个属性,笛卡尔树满足堆的性质。
下面以满足小根堆性质的笛卡尔树为例。
比如说,对于这个序列:,造出来的笛卡尔树就是:
建树也很简单,从左到右依次插入每个节点,用一个栈来维护笛卡尔树的右链,即根节点到最右边的节点这条路径,其中根节点在栈底。
插入节点 时,将栈中值大于 的节点都踢掉,然后将 插入为栈顶的右儿子,栈顶的原右儿子变成 的左儿子,由于 也在右链上了,所以 也要加入到栈里。
可以发现,每次插入的新节点一定在右链的底端,这就能保证对于 满足二叉搜索树的性质,而每次 就接在一个值比他小的点下,并且它的儿子的值都比他大,于是对于 又满足了堆性质。
并且,每个点只会进出一次栈,所以时间复杂度是 的。
题表
以后还会更新的……