模板:左偏树

文章目录

  • 解析
  • 可以解决的问题
    • 定义:
    • 左偏树的基本性质
    • 基本结论
  • 操作
    • 合并
    • 访问与删除堆顶元素
    • 插入元素
    • 批量插入
    • 删除已知元素

所谓左偏树,就是往左偏的树

下面介绍一下它的一个兄弟:
在这里插入图片描述
《右偏树》
(逃)

解析

所谓左偏树,确实就是往左偏的树
它舍弃了平衡的性质,使这个堆在合并时变得极为高效
所以又叫做可并堆
代码实现起来还是很好写的

可以解决的问题

似乎基本上是起一个工具人的作用
出现在题解中“…对于某某信息,维护可并堆即可”这样的地方
不会确实不行呀 qwq

定义:

外结点 :左儿子或右儿子是空结点的结点。
距离 : 一个结点 x 的距离 dist(x)定义为其子树中与结点 x 最近的外结点到 x 的距离。特别地,定义空结点的距离为 -1 。

左偏树的基本性质

左偏树具有堆性质 ,即若其满足小根堆的性质,则对于每个结点 x 有vx<vlsv_x<v_{ls}vx<vlsvx<vrsv_x<v_{rs}vx<vrs
左偏树具有 左偏性质 ,即对于每个结点 x ,有 distlc≥distrcdist_{lc}\ge dist_{rc}distlcdistrc

基本结论

结点 x 的距离 distx=distrc+1dist_x=dist_{rc}+1distx=distrc+1
距离为 n 的左偏树至少有 2n+1−12^{n+1}-12n+11个结点。此时该左偏树的形态是一棵满二叉树。
有 n 的结点的左偏树的根节点的距离是 O(log⁡2n)O(\log_2 n)O(log2n)

(以上参考自:https://www.luogu.com.cn/blog/hsfzLZH1/solution-p3377)

上面的性质还是比较显然的
下面我们来讲讲具体的操作

操作

合并

左偏树的灵魂
设当前是小根堆,要把x堆与y堆合并
首先,如果x、y有一个为空,直接返回另一个
否则,把值较小的作为根,把根的右儿子与另一个堆合并
递归即可
递归回来的时候还要更新dist并维护左偏的性质
由于左偏树极右链是不超过logn的
因此复杂度为logn
写起来也很好写

int merge(int x,int y){if(!x) return y;else if(!y) return x;if(val[x]>val[y]||(val[x]==val[y]&&id[x]>id[y])) swap(x,y);rs[x]=merge(rs[x],y);if(dis[ls[x]]<dis[rs[x]]) swap(ls[x],rs[x]);dis[x]=dis[rs[x]]+1;return x;
}

访问与删除堆顶元素

把堆顶的左右儿子合并并返回即可

int del(int &x){int res=val[x];x=merge(ls[x],rs[x]);return res;
}

插入元素

把一个元素当成一棵树,与大树合并即可

void insert(int &r,int v){int x=New(v);r=merge(r,x);
}

批量插入

直接插入n次nlogn
开一个队列,把所有元素建成单点的树push进去
每次从队首提两棵树合并并放到队尾
直至只剩下一棵树
复杂度O(n)

void build(){queue<int>q;for(int i=1;i<=n;i++){q.push(New(a[i]));}for(int i=1;i<n;i++){int u=q.front();q.pop();int v=q.front();q.pop();q.push(merge(u,v));}r=q.front();q.pop();
}

删除已知元素

这是一个左偏树的重要优势
它可以在logn的时间内删除任意位置的已知元素
注意这里的“已知”是指已知编号而不是已知权值
删除指定权值的操作是堆很难做到的 (至少对我的知识储备来说)
注意树的性质可能变,所以要一直往上更新

void Del(int x){int f=fa[x];int p=merge(ls[x],rs[x]);fa[p]=f;if(!f){r=p;return;}if(f&&ls[f]==x) ls[f]=p;if(f&&rs[f]==x) rs[f]=p;while(f){if(dis[ls[f]]<dis[rs[f]]) swap(ls[f],rs[f]);if(dis[f]==dis[rs[f]]+1) return;dis[f]=dis[rs[f]]+1;p=f;f=fa[f];}return;
}

thanks for reading!

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

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

相关文章

迎开学水题狂欢赛(舞踏会[dp+三叉树],HH去散步[矩阵快速幂],排序[模拟],铁路旅行[线段树])

快速简单记录老师口胡&#xff08;可能就我自己看得懂了吧…&#xff09; 文章目录T1&#xff1a;舞踏会titlesolutioncodeT2&#xff1a;HH去散步titlesolutioncodeT3&#xff1a;排序titlesolutioncodeT4&#xff1a;铁路旅行titlesolutioncodeT1&#xff1a;舞踏会 title …

CSP2021提高组复赛解析

前言 终于出成绩了我可以写博客辣&#xff0c;官方数据还没出就先放洛谷的题目链接了。 正题 T1-廊桥分配 https://www.luogu.com.cn/problem/P7913 题目大意 有m1m_1m1​种一类飞机&#xff0c;m2m_2m2​种二类飞机&#xff0c;每个飞机有一个占用时间的区间。要给两类飞机…

一起开心集训队第一周训练赛2021/3/14

文章目录比赛链接A CodeForces 1481D AB Graph题意&#xff1a;题解&#xff1a;代码&#xff1a;B CodeForces 1481E Sorting Books题意&#xff1a;题解&#xff1a;代码&#xff1a;C CodeForces 1478D Nezzar and Board题意&#xff1a;题解&#xff1a;代码&#xff1a;D …

使用Azure DevOps持续集成GitHub项目

点击蓝字关注我微软的Azure DevOps是一款软件开发管理工具&#xff0c;整合了需求、代码、编译、测试、发布等所有功能于一身。今天我们就来看看如何用Azure DevOps对自己GitHub上的项目做持续集成&#xff0c;并能在GitHub显示最新编译状态。其实在不久之前&#xff0c;Azure …

[BZOJ 3811]玛里苟斯(线性基)尽量理解的题解

文章目录titlesolutioncodetitle 魔法之龙玛里苟斯最近在为加基森拍卖师的削弱而感到伤心&#xff0c;于是他想了一道数学题。 S 是一个可重集合&#xff0c;S{a1,a2,…,an}。 等概率随机取 S 的一个子集 A{ai1,…,aim}。 计算出 A 中所有元素异或和&#xff0c;记为 x, 求 x^…

CF464E The Classic Problem(线段树 最短路)

CF464E The Classic Problem \(\bigstar\texttt{Hint}\)&#xff1a;发现没有什么好的突破口&#xff1f;为什么不想想怎样才能实现题目中 \(2^x\) 的加减法呢&#xff1f; 可见每次加减法&#xff0c;我们要做的是将添加的 \(1\) 和右边的连续的 \(1\) 合并为一整段&#xff0…

C. Longest Simple Cycle

C. Longest Simple Cycle 题意&#xff1a; 有n条链&#xff0c;第i条链上有c[i]个点&#xff0c;a[i]为第i条链的顶点与第i-1条链的连接点&#xff0c;b[i]为第i条链的最后一个点与第i-1条链的连接点。通过上面的方法连接链会产生很多的环&#xff0c;问这些环的最大长度。 …

【CF813F】Bipartite Checking(线段树分治+可删除并查集)

文章目录titlesolutioncodetitle You are given an undirected graph consisting of n vertices. Initially there are no edges in the graph. Also you are given q queries, each query either adds one undirected edge to the graph or removes it. After each query you…

在.Net Core WebAPI下给Swagger增加导出离线文档功能

一丶前言最近刚接触到Swagger&#xff0c;在github上下载了它的源码和demo学习了一遍&#xff0c;发现这个组件非常好用&#xff0c;不过不足的是它没有导出离线文档的功能&#xff0c;于是乎我就想给它加一个导出功能Swagger Github开源地址二丶思路其实说白了api文档就是一个…

YBTOJ洛谷P4331:数字序列(左偏树)

文章目录题目描述数据范围解析代码题目描述 数据范围 n<1e6n<1e6n<1e6 解析 先考虑简单情况 如果原数列是单调递增的&#xff0c;显然应该使biaib_ia_ibi​ai​ 如果单调递减&#xff0c;应该取中位数 那么原数列如果分成单调递减的几段&#xff0c;那么每一段都取中…

P8441 旭日东升(二维数点经典套路)

P8441 旭日东升 维护一个不可重集合的序列 \(a\)&#xff0c;长度为 \(n\)。支持以下两种操作&#xff1a; l r x 对于每个 \(l\le i\le r\)&#xff0c;将 \(x\) 并入 \(a_i\)。l r 设 \(S\) 把每个 \(l\le i\le r\) 的 \(a_i\) 并在一起的集合&#xff0c;输出 \(S\) 中所有元…

深搜、广搜、搜索剪枝

搜索与回溯讲解 文章目录深搜方向向量&#xff1a;DFS代码&#xff1a;题目讲解&#xff1a;八皇后问题字符序列自然数的拆分广搜BFS代码&#xff1a;题目讲解&#xff1a;瓷砖关系网络bfs与dfs的用途与区别搜索剪枝可行性剪枝最优性剪枝记忆化搜索搜索顺序剪枝题目&#xff1a…

使用logdashboard查看可视化日志

logdashboard日志面板是我在Github写的一个开源项目&#xff0c;旨在让查看日志变的方便快捷。在线预览现在功能有日志检索、趋势图、异常堆栈快速查看、日志详情等logdashboard支持自定义日志模型可以记录更多自定义的属性。logdashboard支持的日志来源有以下两种&#xff0c;…

数论分块专题复习(余数求和+模积和+Ice Rain+The Fool)

文章目录前提知识复习T1&#xff1a;余数求和titlesolutioncodeT2&#xff1a;Ice RaintitlesolutioncodeT3&#xff1a;The FooltitlesolutioncodeT4&#xff1a;模积和titlesolutioncode前提知识复习 整除分块是用于快速处理形似下列式子的方法&#xff0c;是解决莫比乌斯反…

领域驱动设计,让程序员心中有码(六)

领域驱动设计-聚合&#xff0c;一种极简的思维模式引言作为IT技术产业飞速发展的产物&#xff0c;软件工程学已经成为当今时代非常重要的一个学科。作为一名资深的软件开发从业者&#xff0c;我们需要学习的东西实际上已经远远超出了原本在大学教育阶段所接受的知识深度和广度&…

hdu 5094 Maze

题意&#xff1a; n*m大的迷宫 &#xff0c;有p种钥匙。钥匙最多有10种。 然后一个k&#xff0c;然后k行表示 (x1,y1),(x2,y2)直接有门或者墙。 如果g0 &#xff0c;就是有墙&#xff0c; 如果g>0 表示有门&#xff0c;且门需要第g把钥匙才能开。 然后下来一个s&#xff…

数论分块练习([CF830 C]Bamboo Partition + [hdu 6395]Sequence )

文章目录T1&#xff1a;SequencetitlesolutionT2&#xff1a;Bamboo PartitiontitlesolutioncodeT1&#xff1a;Sequence title 传送 solution 一眼就是很裸的矩阵加速 ⌊pl⌋\lfloor\frac{p}{l}\rfloor⌊lp​⌋分块矩阵加速就可以了 [BA1][DC⌊pl⌋010001]\begin{bmatrix}…

YBTOJ:染颜色(KDtree)

文章目录题目描述数据范围解析代码题目描述 数据范围 n≤105,T≤5n\le10^5,T\le5n≤105,T≤5 解析 关键是对问题的转化 考虑一次修改&#xff0c;一个点需要满足哪些条件才可以满足 1.与x的距离不超过lll 2.在x的子树内 这两个条件可以转化为对深度的限制和对dfs序的限制 这样…

Kubernetes初探[1]:部署你的第一个ASP.NET Core应用到k8s集群

Kubernetes简介Kubernetes是Google基于Borg开源的容器编排调度引擎&#xff0c;作为CNCF&#xff08;Cloud Native Computing Foundation&#xff09;最重要的组件之一&#xff0c;它的目标不仅仅是一个编排系统&#xff0c;而是提供一个规范&#xff0c;可以让你来描述集群的架…

01分数规划

参考文章 01分数规划 什么是01分数规划&#xff1a; 给定n个a[i]和b[i]&#xff0c;a[i]和b[i]绑定在一起要选同时选&#xff0c;求sum(a[i]) 除以 sum(b[i]) 的最大值&#xff0c;sum为求和函数 对于这种问题我们可以多定义一个数组x[1…n]&#xff0c;x为bool型只取0或者1,…