//
// main.cpp
// Data Structure TRY1
//
// Created by zr9558 on 6/7/13.
// Copyright (c) 2013 zr9558. All rights reserved.
//
// Data Structures C++ Weiss: P.548 Treap
// any node's priority must be at least as large as its parent's.
#include<iostream>
using namespace std;
#include<vector>
#include<math.h>
template<typename Comparable>
class Treap
{
public:
Treap()
{
nullNode = new TreapNode;
nullNode->left=nullNode->right=nullNode;
nullNode->priority=INT_MAX;
root=nullNode;
}
Treap(const Treap &rhs)
{
nullNode = new TreapNode;
nullNode->left=nullNode->right=nullNode;
nullNode->priority=INT_MAX;
root=nullNode;
root=clone(rhs.root);
}
const Treap & operator=( const Treap &rhs)
{
if( this!=&rhs)
{
makeEmpty();
nullNode = new TreapNode;
nullNode->left=nullNode->right=nullNode;
nullNode->priority=INT_MAX;
root=nullNode;
root=clone(rhs.root);
}
return *this;
}
~Treap() { makeEmpty(); }
void makeEmpty() { makeEmpty(root); delete nullNode;}
bool contains( const Comparable &x) const { return contains(x,root);}
void insert( const Comparable &x) { insert(x,root);}
void remove( const Comparable &x) { remove(x,root);}
void print() { Print(root);}
private:
struct TreapNode
{
Comparable element;
TreapNode *left;
TreapNode *right;
int priority;
TreapNode():left(NULL),right(NULL),priority(INT_MAX){}
TreapNode( const Comparable &e, TreapNode *lt, TreapNode *rt, int pr)
: element(e), left(lt), right(rt), priority(pr)
{}
};
TreapNode *root;
TreapNode *nullNode;
void rotateWithLeftChild( TreapNode * &k2)
{
TreapNode *k1=k2->left;
k2->left=k1->right;
k1->right=k2;
k2=k1;
}
void rotateWithRightChild( TreapNode * &k2)
{
TreapNode *k1=k2->right;
k2->right=k1->left;
k1->left=k2;
k2=k1;
}
void insert( const Comparable &x, TreapNode* & t)
{
if( t==nullNode)
t=new TreapNode( x, nullNode, nullNode, rand());
else if( x<t->element)
{
insert(x,t->left);
if( t->left->priority < t->priority)
rotateWithLeftChild(t);
}
else if( x>t->element)
{
insert(x,t->right);
if( t->right->priority<t->priority)
rotateWithRightChild(t);
}
//else duplicate; do nothing
}
void remove( const Comparable &x, TreapNode* & t)
{
if( t!=nullNode)
{
if(x<t->element)
remove(x,t->left);
else if( x>t->element)
remove(x,t->right);
else
{
// Match found
if( t->left->priority <t->right->priority)
rotateWithLeftChild(t);
else
rotateWithRightChild(t);
if( t!=nullNode) //continue on down
remove(x,t);
else
{
delete t->left;
t->left=nullNode; // At a leaf
}
}
}
}
void makeEmpty( TreapNode *&t)
{
if( t!=nullNode)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t=nullNode;
}
bool contains( const Comparable &x, TreapNode * t) const
{
if( t==nullNode) return false;
else if( x<t->element) return contains(x,t->left);
else if( x>t->element) return contains(x,t->right);
else return true;
}
void Print( TreapNode * &t) const
{
if( t!=nullNode)
{
Print(t->left);
cout<<t->element<<" "<<t->priority<<endl;
Print(t->right);
}
}
TreapNode * clone( TreapNode *t) const
{
if( t==t->left) return nullNode; //key point, can not use t==nullNode, Since cannot test against nullNode;
else return new TreapNode(t->element, clone(t->left), clone(t->right), t->priority);
}
};
int main()
{
Treap<int> T1;
for( int i=0; i<10; ++i)
T1.insert(rand()%113);
Treap<int> T=T1;
T.print();
int x;
while( cin>>x)
{
if( T.contains(x))
{
T.remove(x);
T.print();
}
else cout<<"not contain"<<endl;
}
return 0;
}