废话

这也是个咕了很久才学的算法,现在快省选了再不学就来不及了……

然而模板并没有想象中的难,短短两三行就能写完,但是应用起来就很难了。

正题

笛卡尔树的每个节点有两个属性:ididvalval。对于第一个属性,笛卡尔树满足二叉搜索树的性质,对于第二个属性,笛卡尔树满足堆的性质。

下面以满足小根堆性质的笛卡尔树为例。

比如说,对于这个序列:6,3,2,4,7,8,1,56,3,2,4,7,8,1,5,造出来的笛卡尔树就是:
笛卡尔树小结
建树也很简单,从左到右依次插入每个节点,用一个栈来维护笛卡尔树的右链,即根节点到最右边的节点这条路径,其中根节点在栈底。

插入节点 ii 时,将栈中值大于 val[i]val[i] 的节点都踢掉,然后将 ii 插入为栈顶的右儿子,栈顶的原右儿子变成 ii 的左儿子,由于 ii 也在右链上了,所以 ii 也要加入到栈里。

可以发现,每次插入的新节点一定在右链的底端,这就能保证对于 idid 满足二叉搜索树的性质,而每次 ii 就接在一个值比他小的点下,并且它的儿子的值都比他大,于是对于 valval 又满足了堆性质。

并且,每个点只会进出一次栈,所以时间复杂度是 O(n)O(n) 的。

题表

以后还会更新的……

BZOJ 2616 SPOJ PERIODNI   题解

相关文章:

  • 2021-11-01
  • 2021-10-15
  • 2021-08-05
猜你喜欢
  • 2021-06-18
相关资源
相似解决方案