Cod sursa(job #1071276)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 2 ianuarie 2014 20:44:25
Problema Zeap Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 11.86 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;
        int nr_nodes;
        T min_dif;

        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( int );
        void erase( int );
        bool find( int );
        T max_element();
        T min_element();
        T sum();
        T min_diff();

        void split( int key, Treap &, Treap & );
        void join( int key, Treap , Treap  );

        T lower_bound( int );
        T upper_bound( int );

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

        int count( int );

        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> *&, int, int );
        void erase( Node<T> *&, int );
        bool find( Node<T> *, int );

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

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

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

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

        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 = _priority;
            key = _key;
            maxim = _key;
            minim = _key;
            sum = _key;

            nr_nodes = 1;

            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 );
}

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, int 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( int 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 );

    if ( nod->right && nod->right->priority > nod->priority )
            rotate_right( nod );

    nod->update();
}

template <class T>
void Treap<T>::insert( Node<T> *&nod, int key, int priority = 0 )
{
    if ( nod == NULL )
    {
        if ( priority == 0 )
                priority = nod->generate_priority();

        nod = new Node<T>( key, priority );
    }
    else
    {
        if ( key < nod->key )
                insert( nod->left, key, priority );

        if ( key > nod->key )
                insert( nod->right, key, priority );

        balance( nod );
    }
}

template <class T>
void Treap<T>::insert( int key )
{
    if ( find( key ) == 0 )
    {
        insert( Root, key );
        dim++;
    }
}

template <class T>
void Treap<T>::erase( Node<T> *&nod, int key )
{
    if ( key < nod->key )
            erase( nod->left, key );

    if ( key > nod->key )
            erase( nod->right, key );

    if ( key == nod->key )
    {
        if ( nod->left == NULL && nod->right == NULL )
        {
            delete nod;
            nod = NULL;
        }
        else
        {
            if ( nod->left && nod->right )
            {
                if ( nod->left->priority > nod->right->priority )
                        rotate_left( nod );
                else
                        rotate_right( nod );
            }
            else
            {
                if ( nod->left )
                        rotate_left( nod );
                else
                        rotate_right( nod );
            }

            erase( nod, key );
        }
    }

     if ( nod ) nod->update();
}

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

template <class T>
int Treap<T>::size()
{
    return dim;
}

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( int 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( int key, Treap &TS, Treap &TG )
{
    split( key, Root, TS.Root, TG.Root );
}

template <class T>
void Treap<T>::join( int 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( int key, Treap TS, Treap TG )
{
    join( key, Root, TG.Root, TS.Root );
}

template <class T>
int Treap<T>::position( Node<T> *nod, int 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( int key )
{
    return position( Root, key );
}

template <class T>
T Treap<T>::lower_bound( Node<T> *nod, int 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( int key )
{
    return lower_bound( Root, key );
}

template <class T>
T Treap<T>::upper_bound( Node<T> *nod, int 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( int key )
{
    return upper_bound( Root, key );
}

template <class T>
int Treap<T>::count( Node<T> *nod, int 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( int key )
{
    return count( Root, key );
}

template <class T>
T Treap<T>::min_diff()
{
    return Root->min_dif;
}

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" )
        {
            if ( T.size() > 1 )
                    g << T.min_diff() << "\n";
            else
                    g << "-1\n";

            continue;
        }

        if ( s == "MAX" )
        {
            if ( T.size() > 1 )
                    g << T.max_element() - T.min_element() << "\n";
            else
                    g << "-1\n";

            continue;
        }
    }

    return 0;
}