Treap入门题
2016-09-21 12:24
375 查看
Treap可以说是最简单的平衡树了,核心是利用随机数,使得二叉排序树的各种操作复杂度平均为O(lgn),写起来也是相当简单。
主要功能有:
模板:
几道简单的入门题:
题意:
主要维护一个优先队列,支持插入,删除,取最大值,取最小值。
分析:
很多解法可做,用Treap的话,支持上述四种操作即可。客户端的名称和优先级用一个map映射一下,然后插入的是优先级。
题意:
黑盒,每次可以ADD一个数,黑盒中数列有序,有一个GET操作,可以查找第k大元素,k从0递增(在每次GET操作后递增)
分析:
很多解法可做,用Treap的话,只有支持插入,查询第k大元素即可。
题意:
y从小到大,若y相同,x从小到大,这样给出一些坐标,求每个点覆盖的点个数,即每个点有左下方的点数。
分析:
相当经典的题目,许多数据结构的入门题。
按照输入顺序插入x,每遇到一个数只需计算小于等于当前元素的数有多少个即可,也就是求Rank。
主要功能有:
Struct Tree{ int key, size, fa, son[2]; } void Rotate(int x, int p); //0左旋 1右旋 void Insert(int x,int key) //插入key void Remove(int x,int key) //删除值为key的节点 若有重点只删其中一个 int getKth(int x,int k) //获得第k大的节点 int getRank(int x,int key) //获得值<=key的节点个数 并将其转移到根处 若<key只需将<=换为< int getPrev() //返回比根值小的最大值 若无返回0 int getSucc() //返回比根值大的最小值 若无返回0 int getMax(int r) //返回比最大值 int getMin(int r) //返回最小值
模板:
#include <cstdio> #include <cstdlib> /*************************Treap模板*****************************/ const int MAXN=1e6+9; int cnt,rt; //节点编号从1开始 struct Treap { int key, size, pri, son[2]; //保证父亲的pri大于儿子的pri } T[MAXN]; int newNode(int key) { //新建结点 ++cnt; T[cnt].key=key; T[cnt].pri=rand(); T[cnt].size=1; T[cnt].son[0]=T[cnt].son[1]=0; return cnt; } void Rotate(int &x,int p) { //0左旋 1右旋 int y=T[x].son[!p]; T[x].size=T[x].size-T[y].size+T[T[y].son[p]].size; T[x].son[!p]=T[y].son[p]; T[y].size=T[y].size-T[T[y].son[p]].size+T[x].size; T[y].son[p]=x; x=y; } void Insert(int &x,int key) { //插入结点 if(x == 0)x=newNode(key); else { T[x].size++; int p=key < T[x].key; Insert(T[x].son[!p],key); if(T[x].pri < T[T[x].son[!p]].pri) Rotate(x,p); } } void Remove(int &x,int key) { //删除值为key的节点 if(T[x].key == key) { if(T[x].son[0] && T[x].son[1]) { int p=T[T[x].son[0]].pri > T[T[x].son[1]].pri; Rotate(x,p); Remove(T[x].son[p],key); } else { if(!T[x].son[0]) x=T[x].son[1]; else x=T[x].son[0]; } } else { T[x].size--; int p=T[x].key > key; Remove(T[x].son[!p],key); } } int getKth(int &x,int p) { //找出第p小的节点的编号 if(p == T[T[x].son[0]].size+1) return x; if(p > T[T[x].son[0]].size+1) return getKth(T[x].son[1],p-T[T[x].son[0]].size-1); else return getKth( T[x].son[0],p); } int getRank(int &x,int key) { //找出值小于等于key的节点个数 if(x == 0) return 0; if(T[x].key <= key) return T[T[x].son[0]].size+1+getRank(T[x].son[1],key); else return getRank( T[x].son[0],key); } int getMax(int r) { //得到最大值 while(T[r].son[1])r=T[r].son[1]; return T[r].key; } int getMin(int r) { //得到最小值 while(T[r].son[0])r=T[r].son[0]; return T[r].key; } int getPrev() { //得到根结点的前驱 int x=T[rt].son[0]; if(!x)return 0; while(T[x].son[1])x=T[x].son[1]; return x; } int getSucc() { //得到根结点的后继 int x=T[rt].son[1]; if(!x)return 0; while(T[x].son[0])x=T[x].son[0]; return x; } /*****************************************************************/
几道简单的入门题:
poj 3481
题目:http://poj.org/problem?id=3481题意:
主要维护一个优先队列,支持插入,删除,取最大值,取最小值。
分析:
很多解法可做,用Treap的话,支持上述四种操作即可。客户端的名称和优先级用一个map映射一下,然后插入的是优先级。
poj 1442
题目:http://poj.org/problem?id=1442题意:
黑盒,每次可以ADD一个数,黑盒中数列有序,有一个GET操作,可以查找第k大元素,k从0递增(在每次GET操作后递增)
分析:
很多解法可做,用Treap的话,只有支持插入,查询第k大元素即可。
poj 2352
题目:http://poj.org/problem?id=2352题意:
y从小到大,若y相同,x从小到大,这样给出一些坐标,求每个点覆盖的点个数,即每个点有左下方的点数。
分析:
相当经典的题目,许多数据结构的入门题。
按照输入顺序插入x,每遇到一个数只需计算小于等于当前元素的数有多少个即可,也就是求Rank。
相关文章推荐
- POJ 1442 (treap 求出名次入门)
- poj2761(treap入门)
- poj 1442 Black Box (treap树入门题)
- [您有新的未分配科技点]无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)
- 无旋Treap——从入门到放弃
- treap入门题。。
- UVA 12538 可持久化treap入门
- treap入门
- Treap入门题
- Treap入门笔记
- 非诚勿扰 - HDU 4557 - Treap入门
- 无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)
- Treap入门(转自NOCOW)
- Treap入门(转自NOCOW)
- 旋转还是无旋?treap从入门到想死
- 数据结构入门1—Treap
- poj3481double queue【treap树入门题】
- Java入门知识
- 较多详细注释的excelVBA入门语句
- 关于ASP.NET缓存技术学习入门---页面缓存(OutPut Caching)