P3369 【模板】普通平衡树

news/2026/1/16 21:39:57/文章来源:https://www.cnblogs.com/To-Carpe-Diem/p/19494148

P3369 【模板】普通平衡树

大意

  1. 插入
  2. 删除
  3. 查询排名
  4. 查询排名值
  5. 查询前驱
  6. 查询后继

思路

采用 Splay 和 Treap 两种方式。

Treap

首先 Treap 是一种随机化算法,我们采用 二叉搜索树 + 随机化 的方式实现,具体的来说:

首先我们给每个点都随机赋上一个点权,然后使得这棵树在满足 BST 得到基础上再去满足这个堆的性质。

复杂度证明:

\(D(v)\) 为节点 \(v\) 的深度。引入指示变量 \(I(u, v)\)

\[I(u, v) = \begin{cases} 1, & u \text{ 是 } v \text{ 的祖先} \\ 0, & \text{其他} \end{cases} \]

根据期望的线性性,节点 \(v\) 的深度期望值为:

\[E[D(v)] = \sum_{u=1}^n E[I(u, v)] = \sum_{u=1}^n P(u \text{ 是 } v \text{ 的祖先}) \]

在 Treap 中,\(u\)\(v\) 的祖先,当且仅当在数值区间 \([\min(u, v), \max(u, v)]\) 之间的所有节点中,\(u\) 的随机权值 \(w(u)\) 是最大的。

  • 区间内的节点个数为:\(k = |u - v| + 1\)

由于所有节点的随机权值 \(w(i)\) 独立同分布,区间内任何一个节点成为最大值的概率是相等的。因此:

\[P(u \text{ 是 } v \text{ 的祖先}) = \frac{1}{|u - v| + 1} \]

对所有可能的 \(u\) 进行求和:

\[\begin{aligned} E[D(v)] &= \sum_{u=1}^n \frac{1}{|u - v| + 1} \\ &= \sum_{i=1}^{v-1} \frac{1}{v-i+1} + 1 + \sum_{i=v+1}^n \frac{1}{i-v+1} \\ &< \sum_{k=1}^n \frac{1}{k} + \sum_{k=1}^n \frac{1}{k} \end{aligned} \]

利用调和级数近似公式 \(\sum_{k=1}^n \frac{1}{k} = \ln n + O(1)\)

\[E[D(v)] < 2H_n = O(\log n) \]

结论: Treap 的平均深度随节点数 \(n\) 呈对数级增长。

Splay

我们考虑将每次查询的点或者插入的点都旋转到根,这样可以不让树退化。

但是如果是单旋的话会出现这样的问题

image

我们发现这个玩意压根就没有发生变化,这也就是说,这玩意有可能退化(太可怕了

那么我们采用双旋的方式去解决这个问题,类似这样:

image

我们先把 \(x\) 的父亲更改,再处理 \(x\) 的儿子与 \(y\) 处理,最后让 \(y\) 成为 \(x\) 的儿子。

这样我们就做出了 rotate 函数,在旋转的时候,分为同侧旋转与异侧旋转,如果是同侧的话就旋转 \(y\) 再旋 \(x\),如果是异侧就双次旋转 \(x\)

复杂度证明:

不会。
参考大佬的证明

代码

//Treap#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;#define lc(x) t[x].s[0]
#define rc(x) t[x].s[1]const int MAXN = 1e5 + 5;
const int INF = (1 << 30) - 1;struct node{int s[2], v, p, cnt, sz;void init(int val){v = val, p = rand();cnt = sz = 1;s[0] = s[1] = 0;}
}t[MAXN];int root, tot = 0;void pushup(int x){t[x].sz = t[lc(x)].sz + t[rc(x)].sz + t[x].cnt;
}void rotate(int &x, int d){int y = t[x].s[d];t[x].s[d] = t[y].s[d ^ 1];t[y].s[d ^ 1] = x;pushup(x);pushup(y);x = y;
}void Insert(int &x, int val){if(!x){x = ++ tot;t[x].init(val);return;}if(t[x].v == val) t[x].cnt ++;else{int d = val > t[x].v;Insert(t[x].s[d], val);if(t[t[x].s[d]].p > t[x].p) rotate(x, d);}pushup(x);
}void Delete(int &x, int val){if(!x) return;if(t[x].v == val){if(t[x].cnt > 1) t[x].cnt --;else{if(!lc(x) || !rc(x)) x = lc(x) + rc(x);else{int d = t[rc(x)].p > t[lc(x)].p;rotate(x, d);Delete(t[x].s[d ^ 1], val);}}}else Delete(t[x].s[val > t[x].v], val);if(x) pushup(x);
}int Rank(int x, int val){if(!x) return 1;if(t[x].v == val) return t[lc(x)].sz + 1;if(val < t[x].v) return Rank(lc(x), val);return t[lc(x)].sz + t[x].cnt + Rank(rc(x), val);
}int Val(int x, int k){if(!x) return 0;if(k <= t[lc(x)].sz) return Val(lc(x), k);else if(k <= t[lc(x)].sz + t[x].cnt) return t[x].v;else return Val(rc(x), k - t[lc(x)].sz - t[x].cnt);
}int Pre(int val){int x = root, res = -INF;while(x){if(t[x].v < val) res = t[x].v, x = rc(x);else x = lc(x);}return res;
}int Suc(int val){int x = root, res = INF;while(x){if(t[x].v > val) res = t[x].v, x = lc(x);else x = rc(x);}return res;
}int n, op, x;int main(){srand(time(0));ios::sync_with_stdio(0);cin.tie(0);cin >> n;while(n --){cin >> op >> x;if(op == 1) Insert(root, x);else if(op == 2) Delete(root, x);else if(op == 3) cout << Rank(root, x) << '\n';else if(op == 4) cout << Val(root, x) << '\n';else if(op == 5) cout << Pre(x) << '\n';else cout << Suc(x) << '\n';}return 0;
}//Splay#include<iostream>
using namespace std;#define lc(x) t[x].s[0]
#define rc(x) t[x].s[1]const int MAXN = 1e5 + 5;
const int INF = (1 << 30) - 1;struct node{int s[2], f, v, cnt, sz;void init(int fa, int val){f = fa, v = val;cnt = sz = 1;}
}t[MAXN];int root, tot = 0;void pushup(int x){t[x].sz = t[lc(x)].sz + t[rc(x)].sz + t[x].cnt;
}void rotate(int x){int y = t[x].f, z = t[y].f;int k = (rc(y) == x);t[z].s[rc(z) == y] = x;t[x].f = z;t[y].s[k] = t[x].s[k ^ 1];t[t[x].s[k ^ 1]].f = y;t[x].s[k ^ 1] = y;t[y].f = x;pushup(y);pushup(x);
}void Splay(int x, int k){while(t[x].f != k){int y = t[x].f, z = t[y].f;if(z != k){((lc(z) == y) ^ (lc(y) == x)) ? rotate(x) : rotate(y);}rotate(x);}if(k == 0) root = x;
}void Insert(int val){int x = root, f = 0;while(x && t[x].v != val){f = x;x = t[x].s[val > t[x].v];}if(x) t[x].cnt ++;else{x = ++ tot;if(f){t[f].s[val > t[f].v] = x;}t[x].init(f, val);}Splay(x, 0);
}void Find(int val){int x = root;while(t[x].s[val > t[x].v] && t[x].v != val){x = t[x].s[val > t[x].v];}Splay(x, 0);
}int Pre(int val){Find(val);int x = root;if(t[x].v < val) return x;x = lc(x);while(rc(x)) x = rc(x);Splay(x, 0);return x;
}int Suc(int val){Find(val);int x = root;if(t[x].v > val) return x;x = rc(x);while(lc(x)) x = lc(x);Splay(x, 0);return x;
}void Delete(int val){int pre = Pre(val), suc = Suc(val);Splay(pre, 0), Splay(suc, pre);int x = lc(suc);if(t[x].cnt > 1){t[x].cnt --;Splay(x, 0);}else{lc(suc) = 0;Splay(suc, 0);}
}int Rank(int val){Insert(val);int res = t[lc(root)].sz;Delete(val);return res;
}int Val(int k){int x = root;while(true){if(k <= t[lc(x)].sz){x = lc(x);}else if(k <= t[lc(x)].sz + t[x].cnt){break;}else{k -= (t[lc(x)].sz + t[x].cnt);x = rc(x);}}Splay(x, 0);return t[x].v;
}int n, op, x;int main(){ios::sync_with_stdio(0);cin.tie(0);cin >> n;Insert(-INF), Insert(INF);while(n --){cin >> op >> x;if(op == 1){Insert(x);}else if(op == 2){Delete(x);}else if(op == 3){cout << Rank(x) << '\n';}else if(op == 4){cout << Val(x + 1) << '\n';}else if(op == 5){cout << t[Pre(x)].v << '\n';}else{cout << t[Suc(x)].v << '\n';}}return 0;
}

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

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

相关文章

Python 在 AI 芯片管理中的实战指南——从监控调度到智能优化,让异构算力不再“黑盒”

Python 在 AI 芯片管理中的实战指南 ——从监控调度到智能优化,让异构算力不再“黑盒” 大家好,我是 Echo_Wish。今天咱们聊一个非常接地气、也很前沿的话题: 👉 Python 在 AI 芯片管理中的实际应用价值。 平时我们说 AI 芯片,更容易联想到算力、模型推理、训练性能和…

2026最新校服面料推荐!行业权威榜单发布,安全舒适功能性面料品牌推荐 - 品牌推荐2026

引言 随着教育装备标准化进程加速,校服面料的安全性能、舒适体验与功能创新成为校园采购的核心考量因素。据中国纺织品商业协会校服产业分会最新调研数据显示,全国校服面料合规率已提升至82%,但功能性面料应用比例仍…

2026年中国GEO优化公司实力矩阵:权威推荐与深度解析 - 资讯焦点

前言 2026年,生成式AI(AIGC)已从前沿科技议题,转变为深刻影响企业核心竞争力的商业基础设施。在此背景下,GEO(生成式引擎优化)作为抢占AI搜索流量、构建品牌权威认知的核心战略,其重要性已毋庸置疑。然而,市场…

北京中医健康咨询百姓口碑排行:宝福堂专业靠谱,服务优质价格更亲民 - 资讯焦点

北京中医健康咨询百姓口碑排行:宝福堂专业靠谱,服务优质价格更亲民 在健康意识日益增强的今天,专业、可信且可负担的中医健康咨询服务成为众多百姓的迫切需求。北京汇聚了丰富的中医资源,各类提供咨询服务的机构众…

springboot-vue大学生社团管理系统_254x2yk1

目录系统概述功能模块技术架构创新点应用价值项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作系统概述 SpringBoot-Vue大学生社团管理系统是一款基于前后端分离架构的校园社团管理平台&#xff0c;后端采用…

详细介绍:在 Go 项目中集成国际短信能力:从接口调试到生产环境的最佳实践

详细介绍:在 Go 项目中集成国际短信能力:从接口调试到生产环境的最佳实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-famil…

2026最新农业区域公用品牌服务推荐!国内优质农业品牌建设机构权威榜单发布,助力中国农业特色产业/农产品/地理标志农产品高质量发展 - 品牌推荐2026

引言 随着乡村振兴战略深入推进,农业品牌化已成为提升农产品附加值、增强市场竞争力的核心路径。当前,我国地理标志农产品数量突破3500个,但品牌化进程中仍面临同质化严重、产业链整合不足、文化价值挖掘不深等问题…

Qwen-14B 推理和训练的显存占用对比

目录Qwen-14B(8bit)推理 vs LoRA 训练显存占用注解推理:8bit 权重,KV Cache 按 seq_len≈2K 训练:8bit 权重,Batch=1,seq_len≈2K,开启 gradient checkpoint(不存储中间激活),使用 LoRA 微调 Optimizer:Ad…

救命神器2026继续教育TOP8AI论文工具测评

救命神器2026继续教育TOP8AI论文工具测评 2026年继续教育AI论文工具测评&#xff1a;为何需要这份榜单&#xff1f; 在当前学术环境日益复杂、科研要求持续提升的背景下&#xff0c;继续教育领域的学习者和研究者对高效、专业的写作辅助工具需求愈发迫切。无论是撰写课程论文、…

2026最新服装面料推荐!国内优质面料品牌权威榜单发布,资质与品质双优助力服饰产业升级 国内/山西/上海服装面料服务公司推荐 - 品牌推荐2026

引言 随着消费升级与产业转型加速,服装面料行业对品质稳定性、功能多样性及环保可持续性的要求持续提升。据中国纺织工业联合会最新行业报告显示,2025年国内功能性面料市场规模突破2800亿元,年复合增长率达15.3%,但…

深入解析:零知识证明:不泄露秘密也能自证

深入解析:零知识证明:不泄露秘密也能自证2026-01-16 21:30 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: blo…

安卓神器 --- 字典 之 linguee

安卓神器 --- 字典 之 linguee安卓神器 --- 字典 之 linguee

2026最新农业品牌打造/区域公用品牌/农业区域公用品牌/区域公共品牌/产业振兴/产业高质量发展/农业名牌访谈录推荐 - 品牌推荐2026

引领农业品牌化,农本咨询实力领航 在乡村振兴战略深入推进的当下,农业品牌化已成为提升农产品附加值、促进产业高质量发展的核心路径。2026年,在中国农业品牌建设领域,浙江农本品牌管理咨询有限公司(简称“农本咨…

闲置支付宝消费券回收,你的闲置优惠居然能变钱 - 京顺回收

上海白领李女士整理手机,意外翻出3张总额1500元的支付宝消费券,一看有效期只剩3天。可她最近忙得连逛超市的时间都没有,这些消费券扔了实在可惜,留着又注定要过期,正愁得不知如何是好时,朋友的一句话让她眼前一亮…

救命神器!专科生必看10款一键生成论文工具TOP10测评

救命神器&#xff01;专科生必看10款一键生成论文工具TOP10测评 学术写作新选择&#xff1a;2026年专科生论文工具测评指南 在当前高等教育日益普及的背景下&#xff0c;专科生群体在论文写作中面临着时间紧张、资料查找困难、格式不规范等多重挑战。为了帮助大家更高效地完成论…

贪吃蛇整完了!

C项目实战: C语言项目实战 好哦&#xff0c;下一个写扫雷

提示工程架构师入门:有效提示创作的5个常见问题,解答全在这里!

提示工程架构师入门&#xff1a;5个高频问题解答&#xff0c;帮你避开90%的入门坑&#xff01; 摘要/引言&#xff1a;为什么你用AI总翻车&#xff1f;因为没搞懂“提示工程”的底层逻辑 凌晨1点&#xff0c;运营小李盯着电脑屏幕叹气——他花了2小时写的ChatGPT提示&#xff0…

跨领域AI协作中的数据安全问题,架构师用这3个方法解决

跨领域AI协作中的数据安全问题&#xff1a;架构师的3个系统解决方案 一、引入&#xff1a;一场“不敢开始”的AI协作困境 凌晨3点&#xff0c;某三甲医院的信息科主任李阳盯着电脑屏幕上的合作协议&#xff0c;手指在“数据共享”条款上停了足足10分钟。对面的AI公司负责人张鸣…

安防监控与无线网络项目中PoE供电的稳定性探讨

在安防监控与无线网络项目里&#xff0c;PoE供电的稳定性是系统能否长期可靠运行的关键因素。众多工程案例显示&#xff0c;摄像机夜间掉线、Wi-Fi AP重启、端口供电受限等问题&#xff0c;设备质量并非唯一原因&#xff0c;很多时候在功率规划阶段就已埋下隐患。如今&#xff…

机房,然后狂奔(其一)

信竞小故事(一)1.16 信息竞赛课晚一课间 dyh:(颓废地面向电脑上的两百多行代码)我不行了……怎么还没过…… ysk:(已经燃尽的)网……管……(薅住了已经颓废的dyh) dyh:我跟你讲啊这个二叉树@#¥%……&(…