BZOJ3224 普通平衡树
2016-07-12 03:12
253 查看
题目传送门
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
题解
这道题很明显要用二叉排序树来进行操作,其实是裸题。不过以前没打过splay,考试时教练让我们打splay。没打出来,调了一晚上也没调出来。wwwww。熬夜打了一个treap,还要上课啊。。。。。补觉了。
传送门在这里
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每行输出一个数,表示对应答案题解
这道题很明显要用二叉排序树来进行操作,其实是裸题。不过以前没打过splay,考试时教练让我们打splay。没打出来,调了一晚上也没调出来。wwwww。熬夜打了一个treap,还要上课啊。。。。。补觉了。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstdlib> #include <ctime> using namespace std; const int Maxn = 101111; struct node { int s,v,r,cnt; int ch[2]; }N[Maxn]; int totN, root; const int INF = 1 << 30; void up(int u) { int ls = N[u].ch[0], rs = N[u].ch[1]; N[u].s = N[u].cnt + N[ls].s + N[rs].s; } void Rot(int &u, int d) { int t = N[u].ch[d^1]; N[u].ch[d^1] = N[t].ch[d]; N[t].ch[d] = u; up(u); up(t); u = t; } void Ins(int& u,int val) { if (!u) { u = ++totN; N[u].v = val; N[u].cnt = 1; N[u].s = 1; N[u].r = rand(); } else { ++N[u].s; int k = val < N[u].v ? 0 : 1; if (N[u].v == val) { ++N[u].cnt; return; } Ins(N[u].ch[k], val); if (N[N[u].ch[k]].r > N[u].r) Rot(u, k ^ 1); } } void Del(int& u,int val) { if (!u) return; if (N[u].v == val) { if (N[u].cnt > 1) { --N[u].cnt; --N[u].s; return; } if (!N[u].ch[0] || !N[u].ch[1]) u = N[u].ch[0] + N[u].ch[1]; else { int k = N[N[u].ch[0]].r > N[N[u].ch[1]].r; Rot(u,k); Del(u, val); } } else --N[u].s, Del(N[u].ch[val < N[u].v ? 0 : 1],val); } int Rank(int u, int val) { if (!u) return 0; if (N[u].v == val) return N[N[u].ch[0]].s + 1; if (N[u].v < val) return N[N[u].ch[0]].s + N[u].cnt + Rank(N[u].ch[1],val); else return Rank(N[u].ch[0],val); } int Kth(int u,int k) { if (!u) return 0; if (k <= N[N[u].ch[0]].s) return Kth(N[u].ch[0],k); if (k > N[N[u].ch[0]].s + N[u].cnt) return Kth(N[u].ch[1],k - N[N[u].ch[0]].s - N[u].cnt); return N[u].v; } int pred(int u, int val) { if (!u) return INF; if (val <= N[u].v) return pred(N[u].ch[0],val); int ans = pred(N[u].ch[1],val); if (ans == INF) ans = N[u].v; return ans; } int succ(int u, int val) { if (!u) return INF; if (val >= N[u].v) return succ(N[u].ch[1],val); int ans = succ(N[u].ch[0],val); if (ans == INF) ans = N[u].v; return ans; } int main() { //freopen("A.in","r",stdin); //freopen("A.out","w",stdout); int n, op, x; scanf("%d", &n); srand(time(NULL)); while (n--) { scanf("%d%d", &op, &x); if (op == 1) Ins(root,x); else if (op == 2) Del(root,x); else if (op == 3) printf("%d\n", Rank(root,x)); else if (op == 4) printf("%d\n", Kth(root,x)); else if (op == 5) printf("%d\n", pred(root,x)); else printf("%d\n",succ(root,x)); } return 0; }附:在网上看见了一个模板,把splay,treap和SBT的做法打了出来。
传送门在这里
相关文章推荐
- 【慢速学数据结构】优先队列(堆) 篇
- TreeSet实现Comparable接口覆写compareTo()方法
- 【数据结构】链表
- java数据结构-有序数组
- 【数据结构与算法】String 的简单实现
- HashSetDemo
- 数据结构——c语言描述 第六章(1)二叉树树的基本操作和二叉树的线索化
- 数据结构中时间复杂度和空间复杂度的理解
- Swift 3.0在集合类数据结构上的一些新变化总结
- 浅谈算法和数据结构(4):快速排序
- 浅谈算法和数据结构(3):合并排序
- 浅谈算法和数据结构(2):基本排序算法
- Android Binder机制(二) Binder中的数据结构
- 复习(数据结构):动态数组:c++_stl写法
- 数据结构关于AOV与AOE网的区别
- 二、数据结构与算法--数组
- 数据结构 二叉树的互相遍历求法
- RMQ问题——sparse-table算法
- 数据结构学习笔记(一)基础概念
- 二叉树应用-表达式·表达式树·表达式求值(数据结构基础 第6周)