【数据结构】平衡树

实现功能:

  1. 插入数值
  2. 删除数值
  3. 查询某排名的数字
  4. 查询某数值的排名
  5. 查询前驱后继
const int N = 100010, INF = 1e8;int n;
struct Node
{int l, r; // 左右子结点编号int key, val; // key:结点本身的值 val:为了使二叉树平衡的随机数int cnt, size; // cnt:当前结点的数出现了多少次 size:以当前结点为根的子树中有多少结点
}tr[N];int root, idx; // root:根结点编号 idx:计数器,记录结点编号用到哪了void pushup(int p) // 更新p
{tr[p].size = tr[tr[p].l].size + tr[tr[p].r].size + tr[p].cnt;
}int getnode(int key) // 创建值为key的新结点
{tr[ ++ idx].key = key;tr[idx].cnt = 1;tr[idx].size = 1;tr[idx].val = rand();return idx;
}void zig(int &p) // 右旋 (以p为根)
{int q = tr[p].l;tr[p].l = tr[q].r;tr[q].r = p;p = q;pushup(tr[p].r), pushup(p);
}void zag(int &p) // 左旋 (以p为根)
{int q = tr[p].r;tr[p].r = tr[q].l;tr[q].l = p;p = q;pushup(tr[p].l), pushup(p);
}void build() // 创建treap
{getnode(-INF), getnode(INF);root = 1, tr[1].r = 2;pushup(root);if (tr[1].val < tr[2].val) zag(root);
}void insert(int &p, int key) // 当前在p结点,要创建值为key的结点
{if (!p) p = getnode(key); // p不存在else if (tr[p].key == key) tr[p].cnt ++ ; // 原本就有key的结点else if (tr[p].key > key) // 当前结点的key比新结点的key大{insert(tr[p].l, key);if (tr[tr[p].l].val > tr[p].val) zig(p);}else // 当前结点的key比新结点的key小{insert(tr[p].r, key);if (tr[tr[p].r].val > tr[p].val) zag(p);}pushup(p); // 更新当前结点
}void remove(int &p, int key) // 当前在p结点,要删去值为key的结点
{if (!p) return;else if (tr[p].key == key) // 找到要删去的结点{if (tr[p].cnt > 1) tr[p].cnt -- ; // 想删去的key不止一个else if (tr[p].l || tr[p].r) // 左右子结点至少存在一个{if (!tr[p].r || tr[tr[p].l].val > tr[tr[p].r].val){zig(p);remove(tr[p].r, key);}else if (!tr[p].l || tr[tr[p].l].val < tr[tr[p].r].val){zag(p);remove(tr[p].l, key);}}else p = 0; // 叶子结点}else if (tr[p].key > key) remove(tr[p].l, key); // 当前结点值小于要删去的keyelse if (tr[p].key < key) remove(tr[p].r, key); // 当前结点值大于要删去的keypushup(p);
}int getrank_bykey(int p, int key) // 当前结点为p,给定key找rank
{if (!p) return 0;else if (tr[p].key == key) return tr[tr[p].l].size + 1; // 当前结点即为要找的结点else if (tr[p].key > key) return getrank_bykey(tr[p].l, key); // 要找的结点在当前左子树中else if (tr[p].key < key) return tr[tr[p].l].size + tr[p].cnt + getrank_bykey(tr[p].r, key); // 要找的结点在当前右子树中
}int getkey_byrank(int p, int rank) // 当前结点为p,给定rank找key
{if (!p) return INF;else if (tr[tr[p].l].size >= rank) return getkey_byrank(tr[p].l, rank); // 要找的结点在当前左子树else if (tr[tr[p].l].size + tr[p].cnt >= rank) return tr[p].key; // 要找的结点即为当前结点else return getkey_byrank(tr[p].r, rank - tr[tr[p].l].size - tr[p].cnt); // 要找的结点在当前右子树
}int getprev(int p, int key) // 当前结点为p,找小于key的最大值
{if (!p) return -INF;else if (tr[p].key >= key) return getprev(tr[p].l, key); // 小于key的结点在当前结点的左子树else if (tr[p].key < key) return max(tr[p].key, getprev(tr[p].r, key)); // 小于key的结点在当前结点or右子树
}int getnext(int p, int key) // 当前结点为p,找大于key的最小值
{if (!p) return INF;else if (tr[p].key <= key) return getnext(tr[p].r, key); // 大于key的结点在当前结点的右子树else if (tr[p].key > key) return min(tr[p].key, getnext(tr[p].l, key)); // 大于key的结点在当前结点or右子树
}

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

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

相关文章

Windows NT 3.5源代码已编译!

2020年5月&#xff0c;Windows NT 3.5 build 782源代码被泄露。然而&#xff0c;它缺少很多文件&#xff0c;包括编译器、链接器、头文件等。大多数这些工具都可以从 Windows NT 3.5 的 SDK 和 DDK 中应用&#xff08;您也可以临时处理 NT 3.51 的 DDK 文件&#xff0c;但之后根…

【Filament】材质系统

1 前言 本文主要介绍 Filament 的材质系统&#xff0c;官方介绍详见 → Filament Materials Guide。材质系统中会涉及到一些空间和变换的知识点&#xff0c;可以参考&#xff1a;【Unity3D】空间和变换、【Unity3D】Shader常量、变量、结构体、函数、【OpenGL ES】MVP矩阵变换、…

Nsis打包Unity Exe文件(通用)

Nsi 脚本 !include "MUI2.nsh"#使用现代UI Unicode true #使用Unicode !define EXENAME "exeName" #定义常量 exe名称 !define SHORTCUT "快捷方式名称" #定义桌面快捷方式的中文名称Name ${EXENAME} #安装程序的title OutFile "${EXENAME…

python/c++ Leetcode题解——2744. 最大字符串配对数目

方法一:两重循环枚举 思路与算法 我们可以直接使用二重循环,枚举给定的数组 words 中的 words[i] 和 words[j] 是否可以匹配。 由于题目规定了数组 words 中包含的字符串互不相同,因此在枚举时,只要保证 i<j,那么每个字符串最多匹配一次。 代码 C++: class Solut…

react-app框架——使用monaco editor实现online编辑html代码编辑器

文章目录 ⭐前言&#x1f496;react系列文章 ⭐配置monaco-editor&#x1f496;引入react-monaco-editor&#x1f496;引入react-app-rewired&#x1f496;通过config-overrides.js添加monaco插件配置 ⭐编辑代码的react页面配置&#x1f496;扩展 可自定义配置语言 ⭐效果⭐总…

嵌入式培训机构四个月实训课程笔记(完整版)-C++和QT编程第一天-C++概述和基础(物联技术666)

网盘链接:https://pan.baidu.com/s/1TKdHdeuDI8XPaakepvSLZQ?pwd=1688 提取码:1688 上午:C++概述 下午:C++基础 教学内容: 1、面向对象:程序=(对象+对象+…) 对象=(算法+数据结构) 2、类与对象: 对象是现实世界中的一个实体,其特征是: • 每一个对象必须…

Salesforce生成式AI聊天机器人「Einstein Copilot」,将于2月发布!

Spring 24宣布&#xff0c;期待已久的Einstein Copilot将于2024年2月落地Salesforce。该生成式AI聊天机器人将用于整个Salesforce产品套件&#xff0c;帮助企业做出更明智的决策&#xff0c;从而改善客户体验。 Einstein Copilot应用于CRM应用程序中&#xff0c;智能回应任何用…

高效实践,JavaScript全屏和退出全屏操作示例

背景 在项目中出现了一个需求&#xff0c;需要实现将页面投屏到屏幕上&#xff0c;并能够进行开启全屏和退出全屏的操作。 尽管网上有许多第三方开源库可供使用&#xff0c;但由于后续业务场景的不确定性&#xff0c;修改源代码可能带来较大的成本和风险。鉴于全屏功能的实现…

机器学习之伯努利分布及二项分布

伯努利分布:又称两点分布或0-1分布,其样本空间只有两个点,一般取{0,1},不同的伯努利分布只是取到这两个值的概率不一样。伯努利分布只有一个参数p(用描述取1的概率),记作 B e r n o u l l ( p ) Bernoull(p) Bernoull(p)或 X X X~ B ( p ) B(p) B(p)读作X服从参数为p的…

valgrind being installed on Arm platform

valgrind安装: tar -jxvf valgrind-3.12.0.tar.bz2 cd valgrind-3.12.0 ./configure make sudo make install2.在ARM的板子上运行valgrind, 程序出现valgrind Fatal error at startup: a function redirection的错误提示。查找了下&#xff0c;发现是因为libc或ld.so库进行过s…

.net core 6 使用注解自动注入实例,无需构造注入 autowrite4net

像java使用autowrite一样使用 1、前提先注册到ioc容器当中 builder.Services.AddScoped 2、nuget引入AutoWrite4Net 3、启用 //启用自动注入 app.UseAutoWrite(); 4、在类上使用注解 [StartAutoWrite] public class NacosController : ControllerBase 5、实例上使用注解 …

2.mac 安装 Visual studio code 整合go开发

目录 概述前置下载关键命令整合C#go配置go插件常见的go工具安装测试 结束 概述 mac 安装 Visual studio code 整合go开发 相关前置文章 go安装及相关配置 文章 前置 官网速递 mac 系统高于等于 10.15.x 可以直接最新版本 我的系统是 10.13 &#xff0c;所以只能安装此版本…

python list.sort方法和内置函数sorted

list.sort 方法会就地排序列表&#xff0c;也就是说不会把原列表复制一份。这也是这个方法的返回值是 None 的原因&#xff0c;提醒你本方法不会新建一个列表。在这种情况下返回 None 其实是Python 的一个惯例&#xff1a;如果一个函数或者方法对对象进行的是就地改动&#xff…

Nginx 如何实现负载均衡?

Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;也是一个 IMAP/POP3/SMTP 代理服务器。由于其具有丰富的功能和出色的性能&#xff0c;Nginx 广泛应用于 Web 开发、负载均衡、反向代理等场景。在负载均衡方面&#xff0c;Nginx 可以实现基于轮询、IP_HASH、URL_HASH 和…

Kubernetes网络模型概述

Kubernetes网络模型设计的一个基础原则是&#xff1a;每个Pod都拥有一个独立的IP地址&#xff0c;并假定所有Pod都在一个可以直接连通的、扁平的网络空间中。所以不管这些Pod是否运行在同一个Node中&#xff0c;都要求它们可以直接通过对方的IP进行访问。由于Kubernetes的网络模…

Redis服务端优化(持久化配置、慢查询、命令及安全配置、内存配置)

文章目录 持久化配置慢查询命令及安全配置内存配置 持久化配置 慢查询 命令及安全配置 漏洞&#xff1a;Redis未授权访问配合SSH key文件利用分析-腾讯云开发者社区-腾讯云 (tencent.com) 漏洞出现的核心的原因有以下几点 Redis未设置密码利用了Redis的config set命令动态修…

ubuntu禁用/启用图形界面

当安装了带图形界的ubuntu的时候&#xff0c;如果觉得图形界面占资源&#xff0c;就需要将图形界面关闭&#xff0c;关闭的方法如下&#xff1a; 1、 打开 /etc/default/grub&#xff0c;修改或增加如下参数&#xff1a; GRUB_CMDLINE_LINUX_DEFAULT"text" GRUB_TE…

python数字图像处理基础(五)——Canny边缘检测、图像金字塔、图像分割

目录 Canny边缘检测原理步骤 图像金字塔1.高斯金字塔2.拉普拉斯金字塔 图像分割图像轮廓检测1.检测轮廓2.绘制轮廓3.补充 Canny边缘检测 梯度是什么? 梯度就是变化的最快的那个方向 edge cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]…

Codeforce s Round 920 (Div. 3) G题 旋转矩阵,斜缀和,平移

Problem - G - Codeforces 目录 题意&#xff1a; 思路&#xff1a; 总思路&#xff1a; 旋转矩阵&#xff1a; 前缀和预处理&#xff1a; 平移的处理&#xff0c;尤其是越界的处理&#xff1a; 核心代码&#xff1a; 题意&#xff1a; 给你个n*m的矩阵&#xff0c;里…

[自动化分布式] Zabbix自动发现与自动注册

abbix 自动发现&#xff08;对于 agent2 是被动模式&#xff09; zabbix server 主动的去发现所有的客户端&#xff0c;然后将客户端的信息登记在服务端上。 缺点是如果定义的网段中的主机数量多&#xff0c;zabbix server 登记耗时较久&#xff0c;且压力会较大 部署 添加zabb…