初探treap
来源:互联网 发布:js中数组添加元素 编辑:程序博客网 时间:2024/05/18 01:54
treap的基本操作
treap类似二分查找树,只是加了一个堆,用随机值维护平衡,只是期望平衡。小数据下表现并不是特别优秀,但是足够用了。
先水两发,之后再继续搞- -、
poj1338 Ugly Numbers
把质因子只含2,3,5的数叫Ugly Number.通式为:
注意到是一个幂次计算,因此大致地有:
代码:
#include <cstdio>#include <cstring>#include <cstdlib>#include <ctime>#include <algorithm>using namespace std;typedef long long type;struct node { type val; int fix; int rank; //增加维护一个rank值,保存以该节点为根子树的节点数目 node* left; node* right; node() { left = right = NULL; } node(type x) { val = x; fix = rand(); left = right = NULL; }};inline int rank(node* &T) { return T == NULL ? 0 : T->rank;}void rotate_left(node* &T) { //printf("rotate_left %d\n", T->val); node* tp = T->right; T->right = tp->left; T->rank = rank(T->left) + rank(T->right) + 1; tp->left = T; tp->rank = rank(tp->left) + rank(tp->right) + 1; T = tp;}void rotate_right(node* &T) { //printf("rotate_right %d\n", T->val); node* tp = T->left; T->left = tp->right; T->rank = rank(T->left) + rank(T->right) + 1; tp->right = T; tp->rank = rank(tp->left) + rank(tp->right) + 1; T = tp;}void insert(node* &T, type& val) { if (T == NULL) { T = new node(val); T->rank = 1; } else if (val == T->val) { return; } else if (val < T->val) { insert(T->left, val); ++T->rank; if (T->left->fix < T->fix) { rotate_right(T); } } else { insert(T->right, val); ++T->rank; if (T->right->fix < T->fix) { rotate_left(T); } }}void erase(node* &T, type& val) { if (val == T->val) { if (T->left == NULL || T->right == NULL) { node* t = T; if (T->left == NULL) { T = T->right; } else { T = T->left; } T->rank = rank(T->left) + rank(T->right) + 1; delete t; } else { if (T->left->fix < T->right->fix) { rotate_right(T); erase(T->right, val); } else { rotate_left(T); erase(T->left, val); } } } else if (val < T->val) { erase(T->left, val); --(T->rank); } else { erase(T->right, val); --(T->rank); }}bool exist(node* &T, type val) { if (T == NULL) { return false; } else if (T->val == val) { return true; } else if (val < T->val) { return exist(T->left, val); } else { return exist(T->right, val); }}void clear(node* &T) { if (T == NULL) return; clear(T->left); clear(T->right); delete T; T = NULL;}const type INF = 0xfffffff;type find_k(node* &T, int k) { //printf("find_k(%d)\n", k); if (k <= 0 || k > rank(T)) { return INF; } else if (k == rank(T->left) + 1) { return T->val; } else if (k <= rank(T->left)) { return find_k(T->left, k); } else { return find_k(T->right, k - 1 - rank(T->left)); }}void visit(node* &T) { if (T == NULL) return; visit(T->left); printf("(%d,%d) ", T->val, T->rank); visit(T->right);}const int MAX = 32;type p2[MAX], p3[MAX], p5[MAX];int main() { p2[0] = p3[0] = p5[0] = 1; for (int i = 1; i < MAX; ++i) { p2[i] = p2[i - 1] << 1; p3[i] = p3[i - 1] * 3; p5[i] = p5[i - 1] * 5; } node* T = NULL; for (int i = 0; i < MAX; ++i) { if (p2[i] <= 0) break; for (int j = 0; j < MAX; ++j) { if (p3[j] <= 0) break; for (int k = 0; k < MAX; ++k) { long long t = p2[i] * p3[j] * p5[k]; if (t <= 0) break; //printf("insert %d\n", t); insert(T, t); } } } //visit(T); //puts(""); int n; while (~scanf(" %d", &n)) { if (n == 0) break; printf("%lld\n", find_k(T, n)); } clear(T); return 0;}
poj1552
这题只需要用到查找操作,遍历维护的
#include <cstdio>#include <cstring>#include <cstdlib>#include <ctime>#include <algorithm>using namespace std;typedef int type;struct node { type val; int fix; node* left; node* right; node() { left = right = NULL; } node(type x) { val = x; fix = rand(); left = right = NULL; }};void rotate_left(node* &T) { node* tp = T->right; T->right = tp->left; tp->left = T; T = tp;}void rotate_right(node* &T) { node* tp = T->left; T->left = tp->right; tp->right = T; T = tp;}void insert(node* &T, type& val) { if (T == NULL) { T = new node(val); } else if (val <= T->val) { insert(T->left, val); if (T->left->fix < T->fix) { rotate_right(T); } } else { insert(T->right, val); if (T->right->fix < T->fix) { rotate_left(T); } }}void erase(node* &T, type& val) { if (val == T->val) { if (T->left == NULL || T->right == NULL) { node* t = T; if (T->left == NULL) { T = T->right; } else { T = T->left; } delete t; } else { if (T->left->fix < T->right->fix) { rotate_right(T); erase(T->right, val); } else { rotate_left(T); erase(T->left, val); } } } else if (val < T->val) { erase(T->left, val); } else { erase(T->right, val); }}bool exist(node* &T, type val) { if (T == NULL) { return false; } else if (T->val == val) { return true; } else if (val < T->val) { return exist(T->left, val); } else { return exist(T->right, val); }}void clear(node* &T) { if (T == NULL) return; clear(T->left); clear(T->right); delete T; T = NULL;}int query(node* &root, node* &T) { if (T == NULL) return 0; return exist(root, (T->val) * 2) + query(root, T->left) + query(root, T->right);}void visit(node* &T) { if (T == NULL) return; visit(T->left); printf("%d ", T->val); visit(T->right);}int main() { node* T = NULL; int n; while (~scanf(" %d", &n) && n != - 1) { while (n != 0) { insert(T, n); //visit(T); //puts(""); scanf(" %d", &n); } printf("%d\n", query(T, T)); clear(T); } return 0;}
HDU5058 So easy
题意类似判断两个集合是否相等。即是否一个数组中的元素在另一个元素中也一定存在。去重后比较即可。但是,同样地,用treap来练习…
代码:
#include <cstdio>#include <cstring>#include <cstdlib>#include <ctime>#include <algorithm>using namespace std;typedef int type;struct node { type val; int fix; node* left; node* right; node() { left = right = NULL; } node(type x) { val = x; fix = rand(); left = right = NULL; }};void rotate_left(node* &T) { node* tp = T->right; T->right = tp->left; tp->left = T; T = tp;}void rotate_right(node* &T) { node* tp = T->left; T->left = tp->right; tp->right = T; T = tp;}void insert(node* &T, type& val) { if (T == NULL) { T = new node(val); } else if (val == T->val) { return; } else if (val < T->val) { insert(T->left, val); if (T->left->fix < T->fix) { rotate_right(T); } } else { insert(T->right, val); if (T->right->fix < T->fix) { rotate_left(T); } }}void erase(node* &T, type& val) { if (val == T->val) { if (T->left == NULL || T->right == NULL) { node* t = T; if (T->left == NULL) { T = T->right; } else { T = T->left; } delete t; } else { if (T->left->fix < T->right->fix) { rotate_right(T); erase(T->right, val); } else { rotate_left(T); erase(T->left, val); } } } else if (val < T->val) { erase(T->left, val); } else { erase(T->right, val); }}bool exist(node* &T, type val) { if (T == NULL) { return false; } else if (T->val == val) { return true; } else if (val < T->val) { return exist(T->left, val); } else { return exist(T->right, val); }}void clear(node* &T) { if (T == NULL) return; clear(T->left); clear(T->right); delete T; T = NULL;}bool query(node* &root, node* &T) { if (T == NULL) return true; return exist(root, T->val) && query(root, T->left) && query(root, T->right);}int main() { int n; type x; node* T1 = NULL, *T2 = NULL; while (~scanf(" %d", &n)) { for (int i = 0; i < n; ++i) { scanf(" %d", &x); insert(T1, x); } for (int i = 0; i < n; ++i) { scanf(" %d", &x); insert(T2, x); } puts(query(T1, T2) && query(T2, T1) ? "YES" : "NO"); clear(T1); clear(T2); } return 0;}
0 0
- 初探treap
- Treap
- Treap
- Treap
- Treap
- Treap
- Treap
- treap
- Treap
- treap
- Treap
- treap
- Treap
- Treap
- treap
- Treap
- Treap
- Treap
- ruby元编程——类定义
- 怎样用hibernate的hql查询查询成map或list
- 写给自己的First,希望坚持下去
- 开发日志 PHP连接mysql数据库
- 面试中常见的问题
- 初探treap
- JSP内置对象
- ruby元编程——编写代码的代码
- IOS--学习笔记_基本控件
- Servlet之线程安全
- 初体验mac编程
- Servlet的配置文件
- A Knight's Journey
- ruby的Array总结