首页 > 其他分享 >左偏树

左偏树

时间:2024-02-24 17:24:38浏览次数:22  
标签:结点 dist log h1 儿子 左偏

左偏树是一种可并堆(一系列的堆),支持以下操作:

  1. 删除一个堆的最值。

  2. 查询一个堆的最值。

  3. 新建一个堆,只包含一个元素。

  4. 合并两个堆。这个复杂度是 \(O(\log)\) 的。

左偏树是一颗二叉树。定义 “外结点” 为儿子数量不等于 \(2\) 的结点,定义每个结点的 \(dist\) 为该结点到最近的外结点的距离。

左偏树满足对于每个节点,左儿子的 \(dist>\) 右儿子的 \(dist\)。

左偏树满足堆的性质,即一个结点是它子树内的最值。

对于 2 操作,输出一个左偏树的根即可。

对于 3 操作,显然很简单。

如果我们实现了 4,则 1 就只需要合并根的左右儿子,然后删除根即可。

如何实现 4 ?我们观察到一个性质。如果左偏树从根出发一直向右走,最多走 \(\log n\) 步,就会到达一个没有子结点的结点 \(x\)。

证明:假设还能继续往下走。注意到 \(x\) 已经是最右的结点了,所以为了使它的祖先们满足左 \(dist>\) 右 \(dist\),如果截取深度为 \(1\sim dth[x]\) 的这一段,必构成满二叉树。满二叉树结点个数是 \(2\) 的幂,所以 \(d[x]\le \log n\)。

根据这个结论,可以设计出 \(O(\log n)\) 的合并堆算法:

  1. 初始有两颗左偏树 \(h1,h2\),不妨 \(h1\) 的根优于 \(h2\)。

  2. 合并 \(h1\) 右节点的子树 和 \(h2\),将合并出来的左偏树作为 \(h1\) 的右儿子。

  3. 如果此时 \(h1\) 右儿子的 \(dist\) 大于左儿子,交换左右儿子。

标签:结点,dist,log,h1,儿子,左偏
From: https://www.cnblogs.com/FLY-lai/p/18031314

相关文章

  • 左偏树/可合并堆
    左偏树/可合并堆代码笔记代码思路主体部分:合并堆(即merge函数)大堆左偏,把小堆和大堆的右儿子合并。感性理解:堆的形态将比较平衡。辅助部分:并查集维护堆关系简化部分:自定义数据类型(structBheap)注意事项:堆的最大数量是\(n+m\)注意考虑堆被删空等细节情况(尤其是题目......
  • 左偏树/可并堆
    20231107左偏树/可并堆将左偏树/可并堆做一个小结,不写我可能就要忘了。。。左偏树,顾名思义,就是保证左子树深度一定大于右子树,同时需要满足堆的性质,于是在合并两个堆的时候的时间复杂度就为\(\logn\),感觉是非常易懂的,具体实现的细节还是有一些。注意我们会用到并查集和......
  • 数据结构——左偏树/可并堆学习笔记
    引入作为树形数据结构的一员——堆,对于取极值拥有着优秀的复杂度,但是,合并两个堆却成为了一个问题。除了朴素算法外,还有什么算法可以合并两个堆呢?正文那么,可并堆是个啥呢?简单来说,它是一个支持合并操作的二叉堆(好像是废话)。首先,简单介绍一下二叉堆的性质,学过的读者可自行跳过。......
  • 【学习笔记】左偏树
    左偏树属于可并堆的一种,可并堆,也就是可以在较低的时间复杂度下完成对两个堆的合并。定义及性质对于一棵二叉树,定义外节点为左儿子或右耳子为空的节点,定义其的\(dist\)为\(1\),而不是外节点的\(dist\)为其到子树中最近的外节点距离\(+1\)。空节点的\(dist\)为\(0\)。例......
  • 左偏树
    模板: #include<bits/stdc++.h>usingnamespacestd;constintMAXN=1e5+10;intn,m,heap[MAXN];intfa[MAXN],ls[MAXN],rs[MAXN],dis[MAXN];booldel[MAXN];intfind(intx){returnx==fa[x]?x:fa[x]=find(fa[x]);}intMerge(int......
  • 左偏树
    左偏树左偏树是一种可以让我们在\(O(\logn)\)的时间复杂度内进行合并的堆式数据结构。为了方便以下的左偏树为小根堆来讨论。定义外结点:左儿子或者右儿子是空节点的结点。距离:一个结点\(x\)的距离\(dis[x]\)定义为其子树中与结点\(x\)最近的外结点到\(x\)的距离......
  • 【P4331 [BalticOI 2004]】Sequence 数字序列 题解(左偏树维护动态区间中位数)
    左偏树维护动态区间中位数。传送门P4331BalticOI2004Sequence数字序列。Solution1我的思路和题解前半部分完全重合了((如果按照单调不增去分割\(a\)序列的话,对于每一段我们能很简单地得出它的最佳答案:中位数。发现严格单调很难做,很难拿捏,考虑对\(a\)序列的每一项都进......
  • 左偏树学习笔记
    一、前言左偏树是一种可以在\(O(\logn)\)内快速合并的堆式数据结构。具体来说,插入一个元素:\(O(\logn)\)。查询最值:\(O(1)\)。删除最值:\(O(\logn)\)。合并:\(O(\logn)\)。减少一个元素的值:\(O(\logn)\)。同时它可以持久化。二、定义外节点:左儿子或者右儿子为空的......
  • 洛谷P1552 [APIO2012] 派遣 题解 左偏树
    题目链接:https://www.luogu.com.cn/problem/P1552题目大意:每次求子树中薪水和不超过\(M\)的最大节点数。解题思路:使用左偏树维护一个大根堆。首先定义一个Node的结构体:structNode{ints[2],c,sz,dis;longlongsum;Node(){};Node(int_c){s......
  • 洛谷 P3377 【模板】左偏树(可并堆)题解 左偏树模板题
    题目链接:https://www.luogu.com.cn/problem/P3377维护左偏树的同时还需要维护一个并查集。但是并查集也就一个find操作。pop的时候更新f[x]的操作很神奇。示例程序:#include<bits/stdc++.h>usingnamespacestd;constintmaxn=1e5+5;intn,m,op,x,y,val[m......