学会 BST 后,Treap 就比较好学了。
在 BST 的基础上,给每个节点加个随机的优先值,然后类似 Heap 的维护,让树中每个父节点的优先值大于子节点的优先值。
这样随机以后,树高的期望高度被证明为 log(n)。
从而使得操作的复杂度为 log(n) 。
/*
Title : Treap
Author: nyist_xiaod
Date : 2013.3.17
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
template<typename T>
struct Treap
{
struct Node
{
T value;
int key;
Node *lson, *rson;
Node(const T& val):value(val),key(rand()),lson(NULL),rson(NULL){}
};
Node* Root;
/**********************************************/
Treap():Root(NULL){}
void clear(Node* &root)
{
if(root == NULL)
return ;
clear(root->lson);
clear(root->rson);
delete root;
root = NULL;
}
Node* least(Node* root)
{
return root->lson ? least(root->lson) : root;
}
Node* most(Node* root)
{
return root->rson ? most(root->rson) : root;
}
Node* search(const T& value)
{
for(Node *root=Root ; root ; root = value<root->value ? root->lson : root->rson)
if(value == root->value)
return root;
return NULL;
}
void rotate_l(Node* &root)
{
Node* tmp = root->rson;
root->rson = tmp->lson;
tmp->lson = root;
root = tmp;
}
void rotate_r(Node* &root)
{
Node* tmp = root->lson;
root->lson = tmp->rson;
tmp->rson = root;
root = tmp;
}
void insert(Node* &root,const T& value)
{
if(root == NULL)
{
root = new Node(value);
return ;
}
if(value == root->value)
return ;
if(value < root->value)
{
insert(root->lson,value);
if(root->lson->key > root->key)
rotate_r(root);
}
else
{
insert(root->rson,value);
if(root->rson->key > root->key)
rotate_l(root);
}
}
void insert(const T& value)
{
insert(Root,value);
}
void erase(Node* &root,const T& value)
{
if(root == NULL)
return ;
if(value == root->value)
{
if(root->lson && root->rson)
{
if(root->lson->key > root->rson->key)
{
rotate_r(root);
erase(root->rson,value);
}
else
{
rotate_l(root);
erase(root->lson,value);
}
}
else
{
Node* tmp = root;
root = root->rson ? root->rson : root->lson;
delete tmp;
}
}
else
if(value < root->value)
erase(root->lson,value);
else
erase(root->rson,value);
}
void erase(const T& value)
{
erase(Root,value);
}
};
***********************************************************************8
/*
Title : Treap
Author: nyist_xiaod
Date : 2013.5.1
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
template<typename T>
struct Treap
{
struct Node
{
T v;
int key,size;
Node* son[2];
Node(const T& val):v(val),key(rand()),size(1){son[0]=son[1]=NULL;}
int get_size(){
return this ? size : 0;
}
void up(){
if(this) size = son[0]->get_size() + son[1]->get_size() + 1;
}
};
Node* Root;
/**********************************************/
Treap():Root(NULL){}
void clear(Node* &root)
{
if(root == NULL)
return ;
clear(root->son[0]);
clear(root->son[1]);
delete root;
root = NULL;
}
Node* search(const T& v)
{
for(Node *root=Root ; root ; root = v < root->v ? root->son[0] : root->son[1])
if(v == root->v)
return root;
return NULL;
}
void rotate(Node* &root,bool dir) // 0:left , 1:right
{
Node* tmp = root->son[!dir];
root->son[!dir] = tmp->son[dir];
tmp->son[dir] = root;
root->up();
tmp->up();
root = tmp;
}
void insert(Node* &root,const T& v)
{
if(root == NULL)
{
root = new Node(v);
return ;
}
if(v == root->v)
return ;
bool dir = v > root->v;
insert(root->son[dir],v);
if(root->son[dir]->key > root->key)
rotate(root,!dir);
else
root->up();
}
void erase(Node* &root,const T& v)
{
if(root == NULL)
return ;
if(v == root->v)
{
if(root->son[0] && root->son[1])
{
bool dir = root->son[0]->key > root->son[1]->key;
rotate(root,dir);
erase(root->son[dir],v);
}
else
{
Node* tmp = root;
root = root->son[1] ? root->son[1] : root->son[0];
delete tmp;
return ;
}
}
else
{
bool dir = v > root->v;
erase(root->son[dir],v);
}
root->up();
}
Node* kth(Node* root,int k)
{
int lsize = root->son[0]->get_size();
if(k-1 == lsize)
return root;
else
if(k-1 < lsize)
return kth(root->son[0],k);
else
return kth(root->son[1],k-lsize-1);
}
int rank(Node* root,const T& v)
{
if(root == NULL)
return 0;
int lsize = root->son[0]->get_size();
if(v == root->v)
return lsize + 1;
else
if(v < root->v)
return rank(root->son[0],v);
else
return lsize + 1 + rank(root->son[1],v);
}
void insert(const T& v){
insert(Root,v);
}
void erase(const T& v){
erase(Root,v);
}
void kth(int k){
if(k > Root->get_size())
puts("invalid");
else
printf("%d\n",kth(Root,k)->v);
}
void rank(const T& v){
printf("%d\n",rank(Root,v-1));
}
};
int main()
{
//freopen("in.ads","r",stdin);
int Q,x;
char str[8];
Treap<int> S;
while(~scanf("%d",&Q))
{
S.clear(S.Root);
while(Q--)
{
scanf("%s%d",str,&x);
if(str[0] == 'I')
S.insert(x);
else if(str[0] == 'D')
S.erase(x);
else if(str[0] == 'K')
S.kth(x);
else
S.rank(x);
}
}
return 0;
}
***********************************************************************final template after 1 year.
/*
Title : Treap
Author: nyist_xiaod
Date : 2014.5.1
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
template<typename T>
struct Treap {
struct Node {
T val;
int key,sz;
Node *s[2];
Node(T val):val(val),key(rand()),sz(1) {
s[0] = s[1] = NULL;
}
int size() {
return this ? sz : 0;
}
void up() {
if(this)
sz = s[0]->size() + s[1]->size() + 1;
}
};
typedef Node* P;
P root;
Treap():root(NULL) {}
void clear(P &u) {
if(u == NULL)
return ;
clear(u->s[0]);
clear(u->s[1]);
delete u;
u = NULL;
}
P search(T v) {
for(Node *u=root;u != NULL;u = v < u->v ? u->s[0] : u->s[1])
if(v == u->v)
return u;
return NULL;
}
void rotate(P &u,bool d) {
P v = u->s[!d];
u->s[!d] = v->s[d];
v->s[d] = u;
u->up();
v->up();
u = v;
}
void insert(P &u,T val) {
if(u == NULL) {
u = new Node(val);
return ;
}
if(val == u->val) {
//++(u->sz);
return ;
}
bool dir = val > u->val;
insert(u->s[dir],val);
if(u->s[dir]->key > u->key)
rotate(u,!dir);
else
u->up();
}
void erase(P &u,T val) {
if(u == NULL)
return ;
if(val == u->val) {
//if(--(u->sz) == 0) {
if(u->s[0] && u->s[1]) {
bool d = u->s[0]->key > u->s[1]->key;
rotate(u,d);
erase(u->s[d],val);
}
else {
P cp = u;
u = u->s[1] ? u->s[1] : u->s[0];
delete cp;
return ;
}
//}
}
else {
bool d = val > u->val;
erase(u->s[d],val);
}
u->up();
}
P kth(P u,int k) {
int lsz = u->s[0]->size();
if(k - 1 == lsz)
return u;
else
if(k - 1 < lsz)
return kth(u->s[0], k);
else
return kth(u->s[1], k - lsz - 1);
}
int rank(P u,T val) {
if(u == NULL)
return 0;
int lsz = u->s[0]->size();
if(val == u->val)
return lsz + 1;
else
if(val < u->val)
return rank(u->s[0],val);
else
return lsz + 1 + rank(u->s[1],val);
}
void insert(T val) {
insert(root,val);
}
void erase(T val) {
erase(root,val);
}
int kth(int k) {
if(k > root->size())
return root->size() + 1;
else
return kth(root,k)->val;
}
int rank(T val) {
return rank(root,val - 1) + 1;
}
};