POJ 1442 Black Box(treap树)
来源:互联网 发布:点赞数据库设计 编辑:程序博客网 时间:2024/06/07 00:41
题目链接:点击打开链接
思路:treap树模板题, 可以动态维护一个有序表, 支持在O(logN)的时间内完成插入、删除一个元素和查找第K大元素的任务。 当然, treap树能做到的还远远不止这些, 常常与其他数据结构嵌套。
treap树是一种平衡二叉搜索树, 既满足堆的条件, 又满足排序二叉树的条件。
细节参见代码:
#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <string>#include <vector>#include <stack>#include <bitset>#include <cstdlib>#include <cmath>#include <set>#include <list>#include <deque>#include <map>#include <queue>#include <ctime>#define Max(a,b) ((a)>(b)?(a):(b))#define Min(a,b) ((a)<(b)?(a):(b))using namespace std;typedef long long ll;typedef long double ld;const ld eps = 1e-9, PI = 3.1415926535897932384626433832795;const int mod = 1000000000 + 7;const int INF = 0x3f3f3f3f;const int seed = 131;const ll INF64 = ll(1e18);const int maxn = 3e4 + 10;int T,n,m,a[maxn], cc, v;struct treap { int root, treapcnt, key[maxn],priority[maxn], childs[maxn][2], cnt[maxn], _size[maxn]; treap() { root = 0; treapcnt = 1; priority[0] = INF; _size[0] = 0; } void update(int x) { _size[x] = _size[childs[x][0]] + cnt[x] + _size[childs[x][1]]; } void _rotate(int &x, int t) { int y = childs[x][t]; //为了维持平衡而做的旋转操作,它并不直观 childs[x][t] = childs[y][1-t]; childs[y][1-t] = x; update(x); update(y); x = y; } void _insert(int &x, int k) { if(x) { //x == 0 表示该结点为空, 反之非空 if(key[x] == k) cnt[x]++; //cnt[x]表示结点x的值的个数,key[x]表示结点x的值 else { int t = key[x] < k; //根据排序二叉树规则递归下去 _insert(childs[x][t], k); if(priority[childs[x][t]] < priority[x]) { //根据堆排序规则 _rotate(x, t); } } } else { x = treapcnt++; //创建新的结点 key[x] = k; cnt[x] = 1; priority[x] = rand(); //如果优先级是随机的,那么可以证明treap的期望深度是logN childs[x][0] = childs[x][1] = 0; //0表示为空 } update(x); } void _erase(int &x, int k) { if(key[x] == k) { if(cnt[x] > 1) --cnt[x]; else { if(childs[x][0] == 0 && childs[x][1] == 0) { x = 0; return ; //x设为0表示空 } int t = priority[childs[x][0]] > priority[childs[x][1]]; _rotate(x, t); //直到把该结点旋转到叶子再删除 _erase(x, k); } } else _erase(childs[x][key[x]<k], k); update(x); } int _getKth(int &x, int k) { if(k <= _size[childs[x][0]]) return _getKth(childs[x][0], k); //size[x]表示以x为根的子树的值得个数 k -= _size[childs[x][0]] + cnt[x]; //如果在右边,那么将要找右边的第k-size小的数 if(k <= 0) return key[x]; return _getKth(childs[x][1], k); } void insert(int k) { _insert(root, k); } void erase(int k) { _erase(root, k); } int getKth(int k) { return _getKth(root, k); }};int main() { while(~scanf("%d%d",&n,&m)) { treap g; for(int i = 1; i <= n; i++) { scanf("%d",&a[i]); } cc = 1; for(int i = 1; i <= m; i++) { scanf("%d",&v); while(v >= cc) g.insert(a[cc++]); printf("%d\n", g.getKth(i)); } } return 0;}
0 0
- POJ 1442 Black Box(treap树)
- 【POJ 1442】Black Box (treap树)
- POJ-1442 Black Box,treap名次树!
- POJ 1442 Black Box(treap树指针实现)
- POJ 1442 Black Box(Treap)
- POJ 1442 Black Box ( Treap )
- POJ 1442 Black Box(Treap)
- POJ 1442 Black Box [treap]
- POJ 1442 Black Box(treap)
- POJ 1442 Black Box [Treap]
- POJ 1442 Black Box Treap
- poj 1442 Black Box(Treap)
- POJ 1442 Black Box (Treap)
- [Treap] poj 1442 Black Box
- POJ 1442 Black Box(堆||treap)
- POJ 1442Black Box【treap模板】
- POJ 1442 Black Box Treap 模板题
- poj 1442 Black box (Treap过~)
- 算法16 之堆排序
- 轻量级Java EE企业应用实战 学习笔记(二)第二章
- iOS之Touch ID的使用
- 机器学习算法解析—逻辑回归分类
- xml中空格换行缩进
- POJ 1442 Black Box(treap树)
- 最全面的Android Studio使用教程
- HDU--2036改革春风吹满地
- Qt: 渐变填充
- Evaluation of Deep Learning Toolkits
- mysql 注释符号
- 算法17 之拓扑排序
- 矩阵关键概念:消元法、A=LU分解等(PartII)
- java乱码解决之道(九)—–总结