Pagini recente » Cod sursa (job #2451112) | Cod sursa (job #1437912) | Cod sursa (job #746913) | Cod sursa (job #945663) | Cod sursa (job #980177)
Cod sursa(job #980177)
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
class Treap
{
private:
class Node
{
public:
const int infinity = int(1e9);
int key;
int priority;
int minim;
int maxim;
int min_diff;
Node *left, *right;
Node( int _key );
void update( );
};
void insert( Node *&, Node *& );
void erase( Node *&, int );
int find( Node *, int );
void spin_left( Node *& );
void spin_right( Node *& );
void balance( Node *& );
public:
Node *R;
Treap(): R( NULL )
{
srand( time( NULL ) );
}
void insert( int );
int erase( int );
int find( int );
int max_diff( );
int min_diff( );
void update( Node *& );
};
int main()
{
ifstream f("zeap.in");
ofstream g("zeap.out");
Treap T;
string s;
int key;
while( f >> s )
{
if ( s == "I" )
{
f >> key;
T.insert( key );
continue;
}
if ( s == "S" )
{
f >> key;
if ( !T.erase( key ) )
g << "-1\n";
continue;
}
if ( s == "C" )
{
f >> key;
g << T.find( key ) << "\n";
continue;
}
if ( s == "MIN" )
{
g << T.min_diff() << "\n";
continue;
}
if ( s == "MAX" )
{
g << T.max_diff() << "\n";
continue;
}
}
return 0;
}
Treap::Node::Node( int _key )
{
key = _key;
priority = rand() + 1;
minim = _key;
maxim = _key;
min_diff = infinity;
left = NULL;
right = NULL;
}
void Treap::Node::update()
{
minim = maxim = key;
if ( left )
maxim = max( maxim, left->maxim ),
minim = min( minim, left->minim );
if ( right )
maxim = max( maxim, right->maxim ),
minim = min( minim, right->minim );
min_diff = infinity;
if ( left )
min_diff = min( min_diff, left->min_diff ),
min_diff = min( min_diff, key - left->maxim );
if ( right )
min_diff = min( min_diff, right->min_diff ),
min_diff = min( min_diff, right->minim - key );
}
void Treap::insert( Node *&n, Node *&p )
{
if ( n == NULL )
{
n = p;
return;
}
if ( p->key < n->key )
insert( n->left, p );
else
if ( p->key > n->key )
insert( n->right, p );
balance( n );
}
void Treap::erase( Node *&n, int key )
{
if ( key < n->key )
erase( n->left, key );
else
if ( key > n->key )
erase( n->right, key );
else
{
int cache = ( ( n->left ) ? 1 : 0 ) + ( ( n->right ) ? 1 : 0 );
if ( cache == 2 )
( n->left->priority > n->right->priority ) ? spin_left(n) : spin_right(n);
else
if ( cache == 1 )
( n->left ) ? spin_left(n) : spin_right(n);
else
delete n, n = NULL;
if ( n != NULL )
erase( n, key );
}
if ( n != NULL )
update( n );
}
int Treap::find( Node *n, int key )
{
if ( n == NULL ) return 0;
if ( n->key == key ) return 1;
if ( n->key > key ) find( n->left, key );
if ( n->key < key ) find( n->right, key );
return 0;
}
void Treap::spin_left( Node *&n )
{
Node *p = n->left;
n->left = p->right;
p->right = n;
update( n );
update( p );
n = p;
}
void Treap::spin_right( Node *&n )
{
Node *p = n->right;
n->right = p->left;
p->left = n;
update( n );
update( p );
n = p;
}
void Treap::balance( Node *&n )
{
if ( n->left && n->priority < n->left->priority )
spin_left( n );
else
if ( n->right && n->priority < n->right->priority )
spin_right( n );
update( n );
}
void Treap::insert( int key )
{
Node *p = new Node(key);
insert( R, p );
}
int Treap::erase( int key )
{
if ( !find( R, key ) ) return 0;
erase( R, key );
return 1;
}
int Treap::find( int key )
{
return find( R, key );
}
int Treap::max_diff()
{
if ( !R || ( !R->left && !R->right ) )
return -1;
return R->maxim - R->minim;
}
int Treap::min_diff()
{
if ( !R || ( !R->left && !R->right ) )
return -1;
return R->min_diff;
}
void Treap::update( Node *&n )
{
n->update();
}