[平衡树模板]Treap
来源:互联网 发布:老七的淘宝店 编辑:程序博客网 时间:2024/05/29 03:18
算法标签 Treap
种下第一棵平衡树…
题目描述 Description
这是一道模板题。
如果觉得这个题水的可以做一下4544压行,是千古神犇花爸爸出的神犇题。
您需要写一种数据结构(可参考题目标题,但是这句话其实并没有什么用233),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
输入描述 Input Description
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
输出描述 Output Description
对于操作3,4,5,6每行输出一个数,表示对应答案
注意:这道题重复数据可以加入Treap
#include <cstdio>#include <cstdlib>#include <algorithm>#include <ctime>using namespace std;const int maxn = 100005;struct node { node *ch[2]; int r, v, s; //v-键值 r-优先级 s - 子树结点个数 inline int cmp(int x) const { return x < v ? 0 : 1; } inline void maintain() { //计算子结点个数 s = 1; if(ch[0] != NULL) s += ch[0] -> s; if(ch[1] != NULL) s += ch[1] -> s; }};void retate(node* &x, int d) //旋转, d = 0 左旋 d = 1 右旋{ node *k = x -> ch[d ^ 1]; x->ch[d ^ 1] = k -> ch[d]; k->ch[d] = x; x->maintain(); k->maintain(); //重新计算子结点个数 x = k;}void insert(node* &x, int k) //在以x为根的子树中插入键值k,修改x{ if(x == NULL) {x = new node(); x -> ch[0] = x -> ch[1] = NULL; x -> v = k; x -> r = rand(); x -> s = 1; }//x为空 else { int d = x -> cmp(k); insert(x -> ch[d], k); if(x -> ch[d] -> r > x -> r) retate(x, d ^ 1); } x -> maintain();}void remove(node* &x, int k) //在以x为根的子树中删除键值k,修改x{ if(x -> v == k) { //k = x.v if(x -> ch[0] == NULL) x = x -> ch[1]; //左子树为空 else if(x -> ch[1] == NULL) x = x -> ch[0]; //右子树为空 else { int d = (x -> ch[0] -> r > x -> ch[1] -> r ? 1 : 0); retate(x, d); remove(x -> ch[d], k); //递归删除 } }else remove(x -> ch[x -> cmp(k)], k); if(x != NULL) x -> maintain();}int Rank(node *x, int k) //查找k的排名{ if(x == NULL) return 1; if(k <= x -> v) return Rank(x ->ch[0], k); else return Rank(x -> ch[1], k) + (x -> ch[0] != NULL ? x -> ch[0] -> s : 0) + 1; }int kth(node *x, int k) //查找第k小元素{ if(x == NULL || k <= 0 || k > x -> s) return 0; int s = (x -> ch[0] == NULL ? 0 : x -> ch[0] -> s); if(s + 1 == k) return x -> v; else if(k <= s) return kth(x -> ch[0], k); else return kth(x -> ch[1], k - s - 1);}int last(node *x, int k) //求k的前驱{ if(x == NULL) return -(1 << 30); if(x -> v < k) return max(x -> v, last(x -> ch[1], k)); else return last(x -> ch[0], k);}int next(node *x, int k) //求k的后继{ if(x == NULL) return (1 << 30); if(x -> v > k) return min(x -> v, next(x -> ch[0], k)); else return next(x -> ch[1], k);}int main(){ freopen("phs.in", "r", stdin); freopen("phs.out", "w", stdout); int cnt = 0, n; scanf("%d", &n); node *root = NULL; for(int x, opt, i = 1; i <= n; ++i) { scanf("%d%d", &opt, &x); if(opt == 1) insert(root, x); else if(opt == 2) remove(root, x); else if(opt == 3) printf("%d\n", Rank(root, x)); else if(opt == 4) printf("%d\n", kth(root, x)); else if(opt == 5) printf("%d\n", last(root, x)); else if(opt == 6) printf("%d\n", next(root, x)); } return 0;}
阅读全文
1 0
- [平衡树模板]Treap
- [模板]平衡树treap
- 【模板】普通平衡树 Treap
- POJ 1442 平衡树Treap新模板
- POJ 1442 平衡树Treap模板
- 【treap模板】【TyvJ 1728】【普通平衡树】
- 【模板】Treap (模板题:洛谷P3369普通平衡树)
- 3224: Tyvj 1728 普通平衡树 P3369 【模板】普通平衡树(Treap/SBT)Treap
- 【模板】【Treap/SBT】【树堆】普通平衡树【洛谷P3369】
- BZOJ 3224 普通平衡树 裸treap模板题
- BZOJ3224:普通平衡树(含SBT、Treap、Splay模板)
- 【模板】【bzoj3224】Tyvj 1728 普通平衡树 Treap
- Treap模板 BZOJ 3224: Tyvj 1728 普通平衡树
- BZOJ1208: [HNOI2004]宠物收养所 平衡树 Treap 模板题
- 平衡树——Treap (含完整模板)
- P3369 【模板】普通平衡树(Treap/SBT)
- 洛谷 P3369 【模板】普通平衡树(Treap/SBT)
- P3369 【模板】普通平衡树(Treap/SBT)
- redis入门
- ACM零起点2017-7-25(sort对结构体排序 PK 自创C语言对结构体快排)
- 头指针链表插入数据方式之任意位置插入
- [LeetCode]28. Implement strStr()
- Egret5.0使用FairyGUI教程(各种坑点)
- [平衡树模板]Treap
- HDFS完全分布式配置
- 使用Git上传项目代码到github(超详细)
- IDC:2017年公有云服务IT基础设施开支增速最快
- React 通过children实现对话框页面跳转
- 1007. 素数对猜想 (20)
- 人生印记
- hdu--1213 How Many Tables(并查集)
- OpenGL学习笔记1:OpenGL概述