标签:treap入门
treap类似二分查找树,只是加了一个堆,用随机值维护平衡,只是期望平衡。小数据下表现并不是特别优秀,但是足够用了。
先水两发,之后再继续搞- -、
把质因子只含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;
}
这题只需要用到查找操作,遍历维护的
#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;
}
题意类似判断两个集合是否相等。即是否一个数组中的元素在另一个元素中也一定存在。去重后比较即可。但是,同样地,用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;
}
标签:treap入门
原文地址:http://blog.csdn.net/bit_line/article/details/45458831