Treap树堆(bzoj 3224: Tyvj 1728 普通平衡树)
2017-07-20 13:08
453 查看
Treap树堆:一种排序二叉树(中序遍历权值有序)
每个节点有两个关键字:key[]和rand[]
其中key[]满足二叉搜索树性质,rand[]满足堆性质(即Tree+Heap=Treap)即
如果vl是u的左孩子,则key[vl]<key[u],rand[vl]<rand[u]
如果vr是u的右孩子,则key[vr]>key[ur],rand[vr]<rand[u],但rand[vr]和rand[vl]的大小关系不确定
每次插入节点x时先按key[]值插入满足二叉搜索树的性质,插入之后,随机生成该节点rand[]值,之后按rand[]值大小调整树的结构(翻转),以满足堆性质,期望树高(logn)
每次删除时将要删除的节点翻转到叶子然后删除(或者翻转到它只有一个儿子的情况)
翻转规则如下:
没了
Submit: 14281 Solved: 6197
[Submit][Status][Discuss]
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
84185
492737
每个节点有两个关键字:key[]和rand[]
其中key[]满足二叉搜索树性质,rand[]满足堆性质(即Tree+Heap=Treap)即
如果vl是u的左孩子,则key[vl]<key[u],rand[vl]<rand[u]
如果vr是u的右孩子,则key[vr]>key[ur],rand[vr]<rand[u],但rand[vr]和rand[vl]的大小关系不确定
每次插入节点x时先按key[]值插入满足二叉搜索树的性质,插入之后,随机生成该节点rand[]值,之后按rand[]值大小调整树的结构(翻转),以满足堆性质,期望树高(logn)
每次删除时将要删除的节点翻转到叶子然后删除(或者翻转到它只有一个儿子的情况)
翻转规则如下:
没了
3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 14281 Solved: 6197
[Submit][Status][Discuss]
Description
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
Input
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)Output
对于操作3,4,5,6每行输出一个数,表示对应答案Sample Input
101 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
10646584185
492737
#include<stdio.h> #include<stdlib.h> using namespace std; typedef struct { int l, r; int val, rnd; int size, sum; }Tree; Tree tre[100005]; int n, id, root, ans; void Update(int k) { tre[k].size = tre[tre[k].l].size+tre[tre[k].r].size+tre[k].sum; } void Rtroot(int &k) { int t; t = tre[k].l; tre[k].l = tre[t].r; tre[t].r = k; tre[t].size = tre[k].size; Update(k); k = t; } void Ltroot(int &k) { int t; t = tre[k].r; tre[k].r = tre[t].l; tre[t].l = k; tre[t].size = tre[k].size; Update(k); k = t; } void Insert(int &k, int x) { if(k==0) { k = ++id; tre[k].size = tre[k].sum = 1; tre[k].val = x; tre[k].rnd = rand(); return; } tre[k].size++; if(tre[k].val==x) tre[k].sum++; //如果要插入的权值在树中已有节点,直接更新数量 else if(x>tre[k].val) { Insert(tre[k].r, x); if(tre[tre[k].r].rnd<tre[k].rnd) Ltroot(k); //维护堆性质 } else { Insert(tre[k].l, x); if(tre[tre[k].l].rnd<tre[k].rnd) Rtroot(k); } } void Delete(int &k, int x) { if(k==0) return; if(tre[k].val==x) { if(tre[k].sum>1) { tre[k].sum--; tre[k].size--; return; } //↓删除节点k if(tre[k].l*tre[k].r==0) k = tre[k].l+tre[k].r; else if(tre[tre[k].l].rnd<tre[tre[k].r].rnd) //将k点通过翻转往叶子方向移动,左旋还是右旋看哪种满足堆性质 { Rtroot(k); Delete(k, x); } else { Ltroot(k); Delete(k, x); } } else if(x>tre[k].val) { tre[k].size--; Delete(tre[k].r, x); } else { tre[k].size--; Delete(tre[k].l, x); } } int Query_rank(int k, int x) { if(k==0) return 0; if(tre[k].val==x) return tre[tre[k].l].size+1; else if(x>tre[k].val) return tre[tre[k].l].size+tre[k].sum+Query_rank(tre[k].r,x); else return Query_rank(tre[k].l, x); } int Query_num(int k, int x) { if(k==0) return 0; if(x<=tre[tre[k].l].size) return Query_num(tre[k].l, x); else if(x>tre[tre[k].l].size+tre[k].sum) return Query_num(tre[k].r, x-tre[tre[k].l].size-tre[k].sum); else return tre[k].val; } void Query_pro(int k, int x) { if(k==0) return; if(tre[k].val<x) { ans = k; Query_pro(tre[k].r, x); } else Query_pro(tre[k].l, x); } void Query_sub(int k, int x) { if(k==0) return; if(tre[k].val>x) { ans = k; Query_sub(tre[k].l, x); } else Query_sub(tre[k].r, x); } int main(void) { int t, x, i; scanf("%d", &n); id = root = 0; for(i=1;i<=n;i++) { scanf("%d%d", &t, &x); switch(t) { case 1: Insert(root, x); break; case 2: Delete(root, x); break; case 3: printf("%d\n", Query_rank(root, x)); break; case 4: printf("%d\n", Query_num(root, x)); break; case 5: ans=0; Query_pro(root, x); printf("%d\n", tre[ans].val); break; case 6: ans=0; Query_sub(root, x); printf("%d\n", tre[ans].val); break; } } return 0; }
相关文章推荐
- bzoj3224 Tyvj 1728 普通平衡树(splay/treap)
- BZOJ3224 Tyvj 1728 普通平衡树(Treap)
- 【Treap】[BZOJ 3224]Tyvj 1728 普通平衡树
- 【模板】【bzoj3224】Tyvj 1728 普通平衡树 Treap
- BZOJ-3224 普通平衡树 TYVJ-1728 Treap + Vector
- BZOJ3224[Tyvj 1728 普通平衡树]题解--Treap
- Treap模板 BZOJ 3224: Tyvj 1728 普通平衡树
- bzoj3224 Tyvj 1728 普通平衡树 treap
- 【bzoj3224】Tyvj 1728 普通平衡树 01Trie姿势+平衡树的四种姿势 :splay,旋转Treap,非旋转Treap,替罪羊树
- BZOJ 3224: Tyvj 1728 普通平衡树 treap
- (treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树
- bzoj3224Tyvj 1728 普通平衡树 treap
- 【treap】【bzoj 3224】: Tyvj 1728 普通平衡树
- BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]
- BZOJ 3224 Tyvj 1728 普通平衡树 (Treap)
- [BZOJ3224]Tyvj 1728 普通平衡树 && treap
- 【Treap】[BZOJ 3224]Tyvj 1728 普通平衡树 & 非旋转实现
- bzoj 3224: Tyvj 1728 普通平衡树 treap
- bzoj3224 Tyvj 1728 普通平衡树 非旋转式Treap
- BZOJ 3224 Tyvj 1728 普通平衡树——treap