Cod sursa(job #1071275)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 2 ianuarie 2014 20:42:49
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 12.43 kb
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;

template <class T>
class Node
{
    public:

        int priority;
        T key;
        T minim;
        T maxim;
        ///T sum;
        T min_dif;
        ///int nr_nodes;

        Node *left, *right;

        Node( T/**,int**/ );

        void update();
        ///int generate_priority();
};

template <class T>
class Treap
{
    public:

        Node<T> *Root;
        ///int dim;

        Treap(): Root( NULL )
        {
            ///dim = 0;
            srand( time( NULL ) );
        }

        int size();
        ///void clear();
        void insert( T );
        void erase( T );
        bool find( T );
        T max_element();
        T min_element();
        ///T sum();
        T min_diff();
        T max_diff();

        ///void split( T key, Treap &, Treap & );
        ///void join( T key, Treap , Treap  );

        ///T lower_bound( T );
        ///T upper_bound( T );

        ///T kth_element( int );
        ///int position( T );

        ///int count( T );

        ///T operator[]( int pos )
        ///{
            ///return kth_element( pos );
        ///}

        ///void inorder();
        ///void preorder();
        ///void postorder();

    private:

        void rotate_left( Node<T> *& );
        void rotate_right( Node<T> *& );
        void balance( Node<T> *& );

        void insert( Node<T> *&, Node<T> *& );
        void erase( Node<T> *&, T );
        bool find( Node<T> *, T );

        ///T kth_element( Node<T> *, int );
        ///int position( Node<T> *, T );

        ///void split( T, Node<T> *&, Node<T> *&, Node<T> *& );
        ///void join( T, Node<T> *&, Node<T> *&, Node<T> *& );

        ///T lower_bound( Node<T> *, T );
        ///T upper_bound( Node<T> *, T );

        ///int count( Node<T> *, T );

        ///void clear( Node<T> *& );

        ///void inorder( Node<T> * );
        ///void preorder( Node<T> * );
        ///void postorder( Node<T> * );
};

/**template <class T>
int Node<T>::generate_priority()
{
    return ( rand() + 1 );
}
**/
template <class T>
Node<T>::Node( T _key/**, int _priority**/ )
{
    /*priority = rand() + 1;
    key = _key;
    maxim = _key;
    minim = _key;
    ///sum = _key;

    ///nr_nodes = 1;
    min_dif = 1e9;

    left = NULL;
    right = NULL;
    */

    key = _key;
    priority = rand() + 1;
    minim = _key;
    maxim = _key;
    min_dif = 1e9;
    left = NULL;
    right = NULL;
}

template <class T>
void Node<T>::update()
{
    /*minim = maxim = /**sum =/ key;
    ///nr_nodes = 1;
    min_dif = 1e9;

    if ( left )
            minim = min( minim, left->minim ),
            maxim = max( maxim, left->maxim ),
            ///sum += left->sum,
            ///nr_nodes += left->nr_nodes,
            min_dif = min( min_dif, key - left->maxim ),
            min_dif = min( min_dif, left->min_dif );

    if ( right )
            minim = min( minim, right->minim ),
            maxim = max( maxim, right->maxim ),
            ///sum += right->sum,
            ///nr_nodes += right->nr_nodes,
            min_dif = min( min_dif, right->minim - key ),
            min_dif = min( min_dif, right->min_dif );

    **/

    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_dif = 1e9;

    if ( left )
            min_dif = min( min_dif, left->min_dif ),
            min_dif = min( min_dif, key - left->maxim );

    if ( right )
            min_dif = min( min_dif, right->min_dif ),
            min_dif = min( min_dif, right->minim - key );
}

/**template <class T>
void Treap<T>::inorder( Node<T> *nod )
{
    if ( nod->left )
            inorder( nod->left );

    cout << nod->key << " ";

    if ( nod->right )
            inorder( nod->right );
}

template <class T>
void Treap<T>::inorder()
{
    if ( Root ) inorder( Root );
}

template <class T>
void Treap<T>::preorder( Node<T> *nod )
{
    cout << nod->key << " ";

    if ( nod->left )
            inorder( nod->left );

    if ( nod->right )
            inorder( nod->right );
}

template <class T>
void Treap<T>::preorder()
{
    if ( Root ) preorder( Root );
}

template <class T>
void Treap<T>::postorder( Node<T> *nod )
{
    if ( nod->left )
            inorder( nod->left );

    if ( nod->right )
            inorder( nod->right );

    cout << nod->key << " ";
}

template <class T>
void Treap<T>::postorder()
{
    if ( Root ) postorder( Root );
}
*/

template <class T>
T Treap<T>::max_element( )
{
    if ( Root ) return Root->maxim;
}

/**template <class T>
T Treap<T>::sum( )
{
    if ( Root ) return Root->sum;
}
**/

template <class T>
T Treap<T>::min_element( )
{
    if ( Root ) return Root->minim;
}

template <class T>
bool Treap<T>::find( Node<T> *nod, T key )
{
    if ( nod == NULL ) return 0;
    if ( nod->key == key ) return 1;
    if ( key < nod->key ) return find( nod->left, key );
    if ( key > nod->key ) return find( nod->right, key );
}

template <class T>
bool Treap<T>::find( T key )
{
    return find( Root, key );
}

template <class T>
void Treap<T>::rotate_left( Node<T> *&nod )
{
    Node<T> *aux = nod->left;
    nod->left = aux->right;
    aux->right = nod;

    nod->update();
    aux->update();

    nod = aux;
}

template <class T>
void Treap<T>::rotate_right( Node<T> *&nod )
{
    Node<T> *aux = nod->right;
    nod->right = aux->left;
    aux->left = nod;

    nod->update();
    aux->update();

    nod = aux;
}

template <class T>
void Treap<T>::balance( Node<T> *&nod )
{
    if ( nod->left && nod->left->priority > nod->priority )
            rotate_left( nod );
    else
        if ( nod->right && nod->right->priority > nod->priority )
                rotate_right( nod );

    nod->update();
}

template <class T>
void Treap<T>::insert( Node<T> *&n, Node<T> *&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 );
}

template <class T>
void Treap<T>::insert( T key )
{
    ///if ( find( key ) == 0 )
    {
        Node<T> *aux = new Node<T>( key/**, rand() + 1**/ );
        insert( Root, aux );
        ///dim++;
    }
}

template <class T>
void Treap<T>::erase( Node<T> *&n, T 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 ) ? rotate_left(n) : rotate_right(n);
        else
            if ( cache == 1 )
                ( n->left ) ? rotate_left(n) : rotate_right(n);
        else
            delete n, n = NULL;

        if ( n != NULL )
                erase( n, key );
    }

    if ( n != NULL )
            n->update();
}

template <class T>
void Treap<T>::erase( T key )
{
    if ( find( key ) )
            erase( Root, key );
            ///dim--;
}

template <class T>
int Treap<T>::size()
{
    if ( Root && ( Root->left || Root->right ) )
            return 100000;
    else
            return -1;
}

/*template <class T>
T Treap<T>::kth_element( Node<T> *nod, int k )
{
    if ( nod->left == NULL && nod->right == NULL )
            return nod->key;

    int st = 0, dr = 0;

    if ( nod->left  ) st = nod->left->nr_nodes;
    if ( nod->right ) dr = nod->right->nr_nodes;

    if ( st + 1 == k )
    {
        return nod->key;
    }

    if ( st + 1 > k )
    {
        return kth_element( nod->left, k );
    }
    else
    {
        return kth_element( nod->right, k - st - 1 );
    }

    return -1;
}

template <class T>
T Treap<T>::kth_element( int k )
{
    if ( Root && k <= Root->nr_nodes )
            return kth_element( Root, k + 1 );

    return -1;
}

template <class T>
void Treap<T>::clear( Node<T> *&nod )
{
    if ( nod )
    {
        clear( nod->left );
        clear( nod->right );

        delete nod;
        nod = NULL;
    }
}

template <class T>
void Treap<T>::clear()
{
    clear( Root );
}

template <class T>
void Treap<T>::split( T key, Node<T> *&R, Node<T> *&Ts, Node<T> *&Tg )
{
    insert( Root, key, 1000000000 );
    Ts = R->left;
    Tg = R->right;
}

template <class T>
void Treap<T>::split( T key, Treap &TS, Treap &TG )
{
    split( key, Root, TS.Root, TG.Root );
}

template <class T>
void Treap<T>::join( T key, Node<T> *&R, Node<T> *&Ts, Node<T> *&Tg )
{
    R = new Node<T>( key, R->generate_priority() );
    R->left = Ts;
    R->right = Tg;
    erase( Root, R->key );
}

template <class T>
void Treap<T>::join( T key, Treap TS, Treap TG )
{
    join( key, Root, TG.Root, TS.Root );
}

template <class T>
int Treap<T>::position( Node<T> *nod, T key )
{
    static int pos = 0;

    if ( nod == NULL ) return -1;

    if ( nod->key == key )
    {
        int st = 0;

        if ( nod->left )
                st += nod->left->nr_nodes;

        pos += st;

        return pos;
    }

    if ( key < nod->key )
            return position( nod->left, key );
    else
    {
        int st = 1;

        if ( nod->left )
                st += nod->left->nr_nodes;

        pos += st;

        return position( nod->right, key );
    }

    return -1;
}

template <class T>
int Treap<T>::position( T key )
{
    return position( Root, key );
}

template <class T>
T Treap<T>::lower_bound( Node<T> *nod, T key )
{
    static T value = -1;

    if ( nod->key == key )
            value = key;

    if ( key > nod->key )
    {
        value = nod->key;
        if ( nod->right ) lower_bound( nod->right, key );
    }

    if ( key < nod->key )
    {
        if ( nod->left ) lower_bound( nod->left, key );
    }

    return value;
}

template <class T>
T Treap<T>::lower_bound( T key )
{
    return lower_bound( Root, key );
}

template <class T>
T Treap<T>::upper_bound( Node<T> *nod, T key )
{
    static T value = -1;

    if ( nod->key == key )
            value = key;

    if ( key > nod->key )
    {
        if ( nod->right ) upper_bound( nod->right, key );
    }

    if ( key < nod->key )
    {
        value = nod->key;
        if ( nod->left ) upper_bound( nod->left, key );
    }

    return value;
}

template <class T>
T Treap<T>::upper_bound( T key )
{
    return upper_bound( Root, key );
}

template <class T>
int Treap<T>::count( Node<T> *nod, T key )
{
    if ( nod == NULL )
            return 0;

    int st = 0;

    if  ( nod->left )
            st = nod->left->nr_nodes;

    if ( nod->key < key )
            return 1 + st + count( nod->right, key );

    return count( nod->left, key );
}

template <class T>
int Treap<T>::count( T key )
{
    return count( Root, key );
}
*/

template <class T>
T Treap<T>::min_diff()
{
    if ( !Root || ( !Root->left && !Root->right ) )
            return -1;

    return Root->min_dif;
}

template <class T>
T Treap<T>::max_diff()
{
    if ( !Root || ( !Root->left && !Root->right ) )
            return -1;

    return Root->maxim - Root->minim;
}

int main()
{
    ifstream f("zeap.in");
    ofstream g("zeap.out");

    Treap<int> T;
    string s;
    int key;

    while( f >> s )
    {
        if ( s == "I" )
        {
            f >> key;
            T.insert( key );
            continue;
        }

        if ( s == "S" )
        {
            f >> key;

            if ( T.find( key ) )
                    T.erase( key );
            else
                    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;
}