算法合集 | 神奇的笛卡尔树 - HDU 1506

原文地址:https://cs.v8cloud.cn/article.html?blog_id=225

        笛卡尔树是一个很有意思的树形结构,因为它同时满足两个性质,从key(key就是索引位置,如下图中9的key为1,3的key为2......)来看,满足二叉搜索树的特性,从value来看,满足堆的性质。

 

        重点参考下图,图片来自维基百科,还算是能够比较形象的说明这两点。

 

 

        笛卡尔树拥有这两种特性,那么它有什么用途呢?

        

        对于HDU 1506,我们需要计算最大矩形区域,正好是笛卡尔树最典型的用途,从上图中,我们以任意节点K开始,K所在的最大矩形必定是K的value为高,K的右子树最大key值减去K的key值为宽。

 

        笛卡尔树比较难的地方在于构造,小编我是看了好久才把这个思路理清,这里给出大概的思路,不懂得童鞋留言讨论。

 

1、笛卡尔树的构造:

(1)从第一个元素开始,从左往右遍历数组L

(2)将元素L[0]作为树的根节点R

(3)for i in [a[1], a[2]...a[n]]

(4)如果a[i]小于根节点R,则将a[i]作为根节点R的父节点

(5)如果a[i]大于根节点R,则将a[i]从根节点的右节点开始寻找位置

(6)从右寻找的逻辑同根节点的对比方法

 

2、特性

对于树上的每个节点,以它作为高的新矩形的面积就是以该节点为根的子树大小乘以它的

 

构造源代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct node_s
{
    struct node_s * l;
    struct node_s * r;
    struct node_s * p;
    int v;
}node_t;

typedef struct tree_s
{
    node_t * root;
}tree_t;

node_t * node_create(node_t * p, int v)
{
    node_t 
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值