【知识总结】关于笛卡尔树

笛卡尔树:在范围最值查询、范围top k查询等问题上有广泛应用。它具有堆的有序性,中序遍历可以输出原数列。


一、定义与性质

首先先明确,笛卡尔树的构建是根据两个键值来的,第一个是他的if顺序,另一个是他维护的权值(最大或者最小),满足每个节点的根都是两边区间的最小值(性质),比如说 序列 :3 1 5 4 2 它的笛卡尔树就是这样的:

首先,可以看出它满足 id从左到右的顺序,其次每个根都是两边区间最小值。


二、建树

笛卡尔树的建立与单调栈有关,因为这个树要满足id从左到右建立,所以新来的元素 只有两种情况 1.成为 父亲节点(在右) 2.成为儿子节点(在右),但建立过程中会出现 3 1 5 4 2 的情况 5 比1 小 所以 5 成为1 的右儿子,但4又来了,4比5小所以4应该成为5的右父亲,就这么一个过程。具体操作用单调栈还实现:

void get_tree()
{
    int s=0;
    for(int i=1;i<=n;i++)
    {
        while(s&&num[i]<=num[st[s]])
            l[i]=st[s--];//难
        if(st[s]) r[st[s]]=i;//难
        st[++s]=i;
    }
}

用个最简单的例子 来解释 最难理解的那一部分:2 3 4 5 1 和 1  3  4  5 2

2 3 4 5 1:在1到来之前 的链是这样的 3是2的右儿子,4是3的右儿子,5是4的右儿子:

1来了之后 1尝试着去插进去(因为1比之前的小 ,1插入的位置可以确定 哪个区间的最小值)

1在尝试他能插到哪个地方结果插到了顶部,那么这个树的定点就会成为1的左二子,连过去就可以了。

同样地:1 3 4 5 2 刚开始  1 3 4 5 是一条链

最后到1 停了,说明2是1的右儿子,所以1的右儿子指向了2,因为3 4 5 在2左边,所以2的左二子是3,所以该图构建结束。

其实过程就是单调栈的过程所以用单调栈维护建树就可以了。


总结:

笛卡尔树在处理区间的topk问题上还是挺好用的,而且每一个最小值维护的区间可以轻松的看出。方便解决问题

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只酷酷光儿( CoolGuang)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值