原文地址: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