Cod sursa(job #1071930)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 3 ianuarie 2014 18:10:34
Problema Secv8 Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.99 kb
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;

struct T
{
    int key;
    int prior;
    int nr_nodes;
    int rev;

    T *left, *right;

    T( int _key, int _prior )
    {
        key = _key;
        nr_nodes = 1;
        prior = _prior;
        rev = 0;
        left = NULL;
        right = NULL;
    }

    T( T *lf, T *rt )
    {
        key = 0;
        nr_nodes = 1;
        left = lf;
        right = rt;
        if ( lf ) nr_nodes += lf->nr_nodes;
        if ( rt ) nr_nodes += rt->nr_nodes;
    }

} *head;

void update( T *&nod )
{
    if ( nod )
    {
        nod->nr_nodes = 1;

        if ( nod->left )
                nod->left->rev ^= nod->rev,
                nod->nr_nodes += nod->left->nr_nodes;

        if ( nod->right )
                nod->right->rev ^= nod->rev,
                nod->nr_nodes += nod->right->nr_nodes;

        if ( nod->rev )
        {
            swap( nod->left, nod->right );
            nod->rev ^= 1;
        }
    }
}

void rol( T *&nod )
{
    T *aux = nod->left;
    nod->left = aux->right;
    aux->right = nod;

    update( nod );
    update( aux );

    nod = aux;
}

void ror( T *&nod )
{
    T *aux = nod->right;
    nod->right = aux->left;
    aux->left = nod;

    update( nod );
    update( aux );

    nod = aux;
}

void balance( T *&nod )
{
    if ( nod->left && nod->left->prior < nod->prior )
            rol( nod );
    else
        if ( nod->right && nod->right->prior < nod->prior )
                ror( nod );
        else
            update( nod );
}

void insert( T *&nod, int k, int key, int prior )
{
    if ( nod == NULL )
    {
        nod = new T( key, prior );
    }
    else
    {
        update( nod ); update( nod->left ); update( nod->right );

        int st = 0;

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

        if ( k <= st )
                insert( nod->left, k, key, prior );
        else
                insert( nod->right, k - st - 1, key, prior );

        balance( nod );
    }
}

void erase( T *&nod )
{
    if ( nod->left == NULL && nod->right == NULL )
    {
        delete nod;
        nod = NULL;
    }
    else
    {
        update( nod ); update( nod->left ); update( nod->right );

        if ( nod->left && nod->right )
        {
            if ( nod->left->prior > nod->right->prior )
            {
                rol( nod );
                erase( nod->right );
            }
            else
            {
                ror( nod );
                erase( nod->left );
            }
        }
        else
        {
            if ( nod->left )
            {
                rol( nod );
                erase( nod->right );
            }
            else
            {
                ror( nod );
                erase( nod->left );
            }
        }

        update( nod ); update( nod->left ); update( nod->right );
    }
}

int kth_element( T* &nod, int k )
{
    update( nod ); update( nod->left ); update( nod->right );

    int s = 0;

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

    if ( s + 1 == k )
            return nod->key;

    if ( k <= s )
            return kth_element( nod->left, k );
    else
            return kth_element( nod->right, k - s - 1 );
}

void erase(const int i, const int j) {

    T *Ts, *Tr;

    insert(head, i - 1, 0, 0);
    insert(head->right, j - (i - 1), 0, 0);

    Ts = head->left, Tr = head->right->right;

    delete head->right, delete head;

    head = new T(Ts, Tr);
    erase(head);
}

void split(const int i, const int j) {

    T *Ts, *t, *Tr;

    insert( head, i - 1, 0, 0 );
    insert( head->right, j - (i - 1), 0, 0 );

    Ts = head->left, t = head->right->left, Tr = head->right->right;

    t->rev ^= 1;

    delete head->right, delete head;

    head = new T( Ts, t );
    erase( head );
    t = head, head = new T( t, Tr );
    erase( head );
}

void inorder( T *&nod, ostream &f )
{
    if ( nod )
    {
        update( nod ); update( nod->left ); update( nod->right );

        inorder( nod->left, f );
        f << nod->key << " ";
        inorder( nod->right, f );
    }
}

int N, k, e, i, j;
char s[10];

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

    srand( time( NULL) );
    head = NULL;

    f >> N >> e;

    while ( N-- )
    {
        f >> s;

        if ( s[0] == 'I' )
        {
             f >> k >> e;
             insert( head, k - 1, e, rand() + 1 );
        }

        if ( s[0] == 'A' )
        {
            f >> k;

            g << kth_element( head, k ) << "\n";
        }

        if ( s[0] == 'D' )
        {
            f >> i >> j;
            erase( i, j );
        }

        if ( s[0] == 'R' )
        {
            f >> i >> j;

            ///split( i, j );
        }
    }

    inorder( head, g );

    return 0;
}