$\newcommand{\O}{\mathrm{O}}$

Treap は平衡二分探索木の一種で randomness によってその平衡性を保っている.
各ノードはキーおよび優先度を保持しており, 管理する木はキーについて二分探索木の性質を、優先度については(最大値)ヒープ木の性質を満たした構造となっている.
各ノードの優先度については例えば [0, 1] 上の一様分布を独立同分布とすることが多い(以下の実装は異なる).
ちなみに名前の由来は "Tree + Heap" のようだ.
自分の経験的には RBST や Splay Tree よりも速く動作することが多い.
元論文は "Randomized Search Trees" [Aragon, Seidel 1989]
時間計算量: 要素数を $n$ としたとき insert, find, erase $\O (\log n)$ (期待計算量)
template<typename _Key> class TreapNode {
public:
const _Key key;
const unsigned int priority;
TreapNode *left, *right;
TreapNode(const _Key& _key) : key(_key), priority(xor128()), left(nullptr), right(nullptr){}
static unsigned int xor128(){
static unsigned int x = 123456789, y = 362436069, z = 521288629, w = 86675123;
unsigned int t = (x ^ (x << 11));
x = y, y = z, z = w;
return (w = (w ^ (w >> 19)) ^ (t ^ ( t >> 8)));
}
};
// [-inf, key) [key, +inf)
template<typename _Key>
pair<TreapNode<_Key>*, TreapNode<_Key>*> split(TreapNode<_Key> *cur, const _Key& key){
if(!cur) return {nullptr, nullptr};
pair<TreapNode<_Key>*, TreapNode<_Key>*> res;
if(key <= cur->key){
res = split(cur->left, key), cur->left = res.second;
return {res.first, cur};
}else{
res = split(cur->right, key), cur->right = res.first;
return {cur, res.second};
}
}
template<typename _Key>
bool find(TreapNode<_Key> *cur, const _Key& key){
while(cur){
if(cur->key == key) return true;
cur = (key < cur->key ? cur->left : cur->right);
}
return false;
}
template<typename _Key>
TreapNode<_Key> *insert(TreapNode<_Key> *cur, TreapNode<_Key> *new_node){
if(!cur) return new_node;
if(cur->priority < new_node->priority){
pair<TreapNode<_Key>*, TreapNode<_Key>*> res = split(cur, new_node->key);
new_node->left = res.first, new_node->right = res.second;
return new_node;
}else if(new_node->key < cur->key){
cur->left = insert(cur->left, new_node);
}else{
cur->right = insert(cur->right, new_node);
}
return cur;
}
template<typename _Key>
TreapNode<_Key> *join(TreapNode<_Key> *left, TreapNode<_Key> *right){
if(!left || !right) return (left ? left : right);
if(left->priority < right->priority){
return right->left = join(left, right->left), right;
}else{
return left->right = join(left->right, right), left;
}
}
template<typename _Key>
pair<TreapNode<_Key>*, bool> erase(TreapNode<_Key> *cur, const _Key& key){
if(!cur) return make_pair(cur, false);
if(cur->key == key){
TreapNode<_Key> *res = join(cur->left, cur->right);
delete cur;
return make_pair(res, true);
}else if(key < cur->key){
pair<TreapNode<_Key>*, bool> res = erase(cur->left, key);
cur->left = res.first;
return make_pair(cur, res.second);
}else{
pair<TreapNode<_Key>*, bool> res = erase(cur->right, key);
cur->right = res.first;
return make_pair(cur, res.second);
}
}
AOJ : Set: Delete 提出コード