首页 > 其他分享 >笛卡尔树

笛卡尔树

时间:2024-04-06 11:55:05浏览次数:30  
标签:le 右链 笛卡尔 top 最小值 节点

1 定义

笛卡尔树是一种二叉树,每一个节点由二元组 \((k,w)\) 组成。要求 \(k\) 满足二叉搜索树的性质,\(w\) 满足堆的性质。

当 \(k,w\) 都确定,且 \(k,w\) 互不相同时,笛卡尔树的结构是唯一的,如图:

看到这个定义,会发现与 Treap 十分相似。

实际上,Treap 就是一种特殊的笛卡尔树。

通常情况下,将下标作为 \(k\)(如上图)。

2 建树

2.1 过程

首先由定义可以直接得出一个 \(O(n\log n)\) 算法,但是重点不在于此。

笛卡尔树有线性的构造方式。

我们先将所有元素按照 \(k\) 排序,那么这样我们按顺序插入的时候,一定是插入到树的右链(即从根节点不断走向右儿子所形成的链)。

那么此时我们观察右链,假设当前节点是 \(p\),那么现在要满足的就是堆的性质。我们从右链末端开始比较,当出现第一个 \(x\) 满足 \(x_w<p_w\) 时,就将 \(p\) 接到 \(x\) 右儿子上,而 \(x\) 原先的右儿子变为 \(p\) 的左儿子。

如果没有找到这个 \(x\),那么 \(p\) 就成为了根节点。

现在我们考虑维护右链,因为维护右链的过程中就可以建好树。显然右链的 \(w\) 是要满足单调递增的。那么插入元素的过程中维护一个单调递增的结构,这显然是单调栈。

2.2 代码

有了上面的分析,代码就不难了:

int s[Maxn], top;
for(int i = 1; i <= n; i++) {
	int k = top;
	while(k && w[s[k]] > w[i]) k--;
	if(k) rs[s[k]] = i;
	if(k < top) ls[i] = s[k + 1];
	s[++k] = i;
	top = k;
}

3 用途

笛卡尔树适合解决与最值相关的问题,不过先给出一些性质(以小根堆为例):

  1. 以 \(u\) 为根的子树是一段连续的区间,且区间最小值就是 \(u_w\)
  2. 区间上 \([l,r]\) 的最小值就是 \(\text{Lca}(l,r)_w\)。
  3. 若 \(y\) 随机,则树高期望为 \(\log\)。(这样做就是 Treap 了)。

下面举一例:

3.1 [例 1] 最大子矩形问题

形式化题意:给定数组 \(a\),求 \(\max\{\min\limits_{i=l}^r(a_i)\times (r-l+1)\},1\le l\le r\le n\)。

这道题是经典的单调栈题,不过也可以用笛卡尔树。

具体的,我们以下表为 \(k\),值为 \(w\) 建立笛卡尔树。接下来我们枚举最小值,然后找最小值为它的最长区间。

由上面的性质 \(1\)​ 得,最长区间就是子树大小,于是两者相乘取最大值即可。

标签:le,右链,笛卡尔,top,最小值,节点
From: https://www.cnblogs.com/dzbblog/p/18117286

相关文章

  • P7219 [JOISC2020] 星座 3【笛卡尔树+整体dp】
    P7219[JOISC2020]星座3笛卡尔树+整体dp(线段树合并维护dp)考虑转化题意,不存在矩形为星座,即对于每个极大矩形中都只有一颗星星。而观察题目的方格,对于两个位置是否能够成为一个矩形,只和两个位置的区间最大值(小白船的位置)有关①。图中的红蓝矩形即为两个极大矩形。将删除星......
  • P1377 [TJOI2011] 树的序 (笛卡尔树)
    笛卡尔树模板题题目给出一个生成序列要我们构造一个二叉搜索树。所以值要满足二叉搜索树的性质。因为给出的是生成序列,所以序列的下标是满足最小堆的性质。那么可以按照满足二叉搜索树的那一维度进行排序也就是值进行排序。然后进行构建即可。最后进行先序遍历即可获得答......
  • 笛卡尔树学习笔记
    笛卡尔树学习笔记定义笛卡尔树是一棵特殊的二叉树,它的每个节点都包含了两个值\((k,w)\)。其中,整棵树关于\(k\)为一棵二叉搜索树,而关于\(w\)为一个小根堆(或大根堆)。到这里可以发现,Treap是一种特殊的笛卡尔树,因为Treap相当于给定了\(k\),而我们人为将其随机了一个\(w\)......
  • 笛卡尔乘积
    SQL中的笛卡尔积SQL中的笛卡尔积是数学集合论中的一个术语。但是,我们也可以在SQL数据库手册中找到这个术语。它意味着什么,我们应该如何使用它?让我们来学习一下。两个集合X和Y的笛卡尔积,表示为X×Y,是所有有序对的集合,其中x在X中,y在Y中。就SQL而言,笛卡尔积是......
  • 编程语言中,差、交、并、自然连接、选择、投影、笛卡尔积分别都是什么运算...
    原文:https://blog.csdn.net/muzihuaner/article/details/119529646交(Intersection):关系R与关系S的交由既属于R又属于S的元组组成,即R与S中相同的元组,组成一个新关系,其结果仍为n目关系。记作:R∩S={t|t∈R∧t∈S}简单来说,运算结果就是两或多个实体集所共有的部分 并(Union):......
  • 笛卡尔树学习笔记
    1.定义笛卡尔树是一种特殊的二叉树,同时满足小根堆和二叉搜索树的性质,笛卡尔树的每个节点有两个值(k,w),k满足二叉搜索树性质,w满足小根堆性质。Treap也是一种笛卡尔树2.性质如果k,w是分别两两不同的,那么笛卡尔树也是唯一的对于一颗笛卡尔树,它的中序遍历是原序列a在原序列中......
  • 笛卡尔树
    笛卡尔树定义以一个数列为基础,存储数列中元素,满足两个限制的树。一是数列中元素的下标满足二叉搜索树的性质,二是元素的大小满足堆的性质。建树使用单调栈,在线建树。考虑从左往右在已有的笛卡尔树中添加元素,因为新元素的下标最大,所以只可能取代最右链中的某个元素,并将其收为左......
  • <学习笔记> 笛卡尔树
    笛卡尔树是一种二叉树,每一个节点由键值二元组\((k,w)\)构成,\(k\)满足二叉搜索树的性质,\(w\)满足堆的性质。构建我们可以用一个栈进行构建,假如我们想要求\(k\)满足二叉搜索树的性质,那么我们首先需要按\(k\)从小到大排序,然后一个一个插入;假如我们想要\(w\)满足小根......
  • 数据过多时候,子查询改成left join减少笛卡尔积
    子查询SELECT cn.portal_idASportalId, count(id)ASnumFROM construction_package_wbs_nodecnWHERE cn.delete_flag=0 AND( cn.node_type='单位工程' ORcn.node_type='分部工程' ORcn.node_type='分项工程' ORcn.no......
  • 笛卡尔积
    项目中用到了数据组合问题,使用递归实现笛卡尔积,发现报内存溢出,给出解决办法:1functionDescartes1(list){2letresultList=[];3letsrcLength=list.length;4for(leti=1;i<srcLength;i++){5letpreList=i==1?list[i-1]:r......