笛卡尔树

news/发布时间2024/5/17 17:09:46

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\)​ 得,最长区间就是子树大小,于是两者相乘取最大值即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/12074558.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

开源软件

接触编程之后难免会接触到开源的软件,起初觉得很奇怪,这么复杂且封装良好的软件为什么作者会平白无故分享出来?比如一些免费开源的CMS建站系统,当时可是我做网络维护岗位时最喜欢翻弄的东西了,后来随着了解的深入,渐渐发现,其实这些工具面向的除了标准的用户群体,还有一群渴望…

Fiddler(8)设置网络丢包和延迟

1、打开Fiddler工具,点击Rules-Customize Rules 2、打开了一个配置文件,ctrl+F搜索delay,往下找找到设置上行下行延迟的地方 3、修改发送延迟和下载延迟的时间,可以修改的大一些,越大延迟越久,修改后保存4、选择Rules-Performance-Simulate Modem Speed,设置生效 然后刷…

DIY SMU的功率放大电路粗略解析(简单写写,不准备详细解释)

在Dave Erickson的网站上:Dave Erickson DIY SMU Source Measure Unit Project (djerickson.com),提供了DIY SMU所需要的全部资料。 这里对他提供的功率放大电路的仿真电路做一点点修改,然后粗略的做一个解析。简单修改后的功率放大电路如下图所示: U8看起来像不像一个缓冲…

Ubuntu ufw 命令

Ubuntu 22.04 自带ufw 无需下载 ufw是Uncomplicated Firewall的缩写,是一个用户友好的命令行工具,用于管理Ubuntu系统上的防火墙。通过ufw命令,用户可以轻松地配置防火墙规则、查看当前的防火墙状态、启用或禁用防火墙等操作,帮助用户保护系统安全并控制网络流量。查看防火…