Cod sursa(job #1794566)

Utilizator Tiberiu02Tiberiu Musat Tiberiu02 Data 1 noiembrie 2016 14:54:59
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 6.51 kb
# include <iostream>
# include <fstream>
# include <cstdlib>
# include <cassert>

using namespace std;

struct Node
{
    int key, priority;
    int weight;
    bool rvs;
    Node * left, * right;

    Node( int _key, int _priority = -2, Node * _left = NULL, Node * _right = NULL )
    {
        key = _key;
        if ( _priority == -2 )
            priority = rand();
        else
            priority = _priority;
        rvs = false;
        left = _left;
        right = _right;
        weight = 1 + ( left == NULL ? 0 : left->weight ) + ( right == NULL ? 0 : right->weight );
    }
};

class Treap
{
public:
    Treap( void );
    void push( int pos, int key );
    void pop( int pos );
    void pop( int p1, int p2 );
    int kth( int pos );
    void reverse( int p1, int p2 );
    int size( void );
    void print( ofstream &fout );

private:
    Node * root;
    void insert( Node * &n, int pos, int key, int priority );
    void erase( Node * &n, int pos );
    int search( Node * &n, int pos );
    void split( Node * &t, int pos, Node * &t1, Node * &t2 );
    void join( Node * &t, Node * &t1, Node * &t2 );
    int weight( Node * &n );
    void updateWeight( Node * &n );
    void rotLeft( Node * &n );
    void rotRight( Node * &n );
    void balance( Node * &n );
    void lazy( Node * &n );
    void printNode( Node * &n, ofstream &fout );
    void printNode( Node * &n, ostream &fout );
};

void Treap::printNode( Node * &n, ostream &fout )
{
    if ( n == NULL )
        return;
    lazy( n );

    printNode( n->left, fout );
    fout << n->key
    //<< ':' << n->weight
    << ' ';
    printNode( n->right, fout );
}

void Treap::printNode( Node * &n, ofstream &fout )
{
    if ( n == NULL )
        return;
    lazy( n );

    printNode( n->left, fout );
    fout << n->key
     //<< ':' << n->weight
     << ' ';
    printNode( n->right, fout );
}

void Treap::print( ofstream &fout )
{
    printNode( root, fout );
    fout << endl;
}

void Treap::lazy( Node * &n )
{
    if ( n != NULL && n->rvs ) {
        n->rvs = false;
        swap( n->left, n->right );

        if ( n->left != NULL )
            n->left->rvs ^= 1;
        if ( n->right != NULL )
            n->right->rvs ^= 1;
    }
}

void Treap::balance( Node * &n )
{
    if ( n == NULL )
        return;

    updateWeight( n );

    //cout << n->key << endl;
    if ( n->left == NULL && n->right == NULL ) {
        if ( n->priority == -1 ) {
            delete n;
            n = NULL;
        }
        return;
    }

    if ( n->left != NULL && n->left->priority > n->priority ) {
        rotLeft( n );
        balance( n->right );
        updateWeight( n->left );
    } if ( n->right != NULL && n->right->priority > n->priority ) {
        rotRight( n );
        balance( n->left );
        updateWeight( n->right );
    }

    updateWeight( n );
}

void Treap::rotRight( Node * &n )
{
    lazy( n );
    lazy( n->right );

    Node * t = n->right;
    n->right = t->left;
    t->left = n;
    n = t;
}

void Treap::rotLeft( Node * &n )
{
    lazy( n );
    lazy( n->left );

    Node * t = n->left;
    n->left = t->right;
    t->right = n;
    n = t;
}

void Treap::updateWeight( Node * &n )
{
    if ( n != NULL )
        n->weight = 1 + weight( n->left ) + weight( n->right );
}

int Treap::weight( Node * &n )
{
    return ( n == NULL ? 0 : n->weight );
}

void Treap::join( Node * &t, Node * &t1, Node * &t2 )
{
    t = new Node( 0, RAND_MAX, t1, t2 );
    erase( t, weight( t1 ) + 1 );
}

void Treap::split( Node * &t, int pos, Node * &t1, Node * &t2 )
{
    insert( t, pos, 0, RAND_MAX );
    t1 = t->left;
    t2 = t->right;
    delete t;
    t = NULL;
}

int Treap::search( Node * &n, int pos )
{
    updateWeight( n );
    assert( pos > 0 && pos <= weight( n ) );
    lazy( n );

    if ( pos <= weight( n->left ) )
        return search( n->left, pos );
    else if ( pos == weight( n->left ) + 1 )
        return n->key;
    else
        return search( n->right, pos - weight( n->left ) - 1 );
}

void Treap::erase( Node * &n, int pos )
{
    assert( pos <= weight( n ) && n != NULL );
    lazy( n );

    if ( pos == 1 && n->left == NULL && n->right == NULL ) {
        delete n;
        n = NULL;
    }
    if ( pos <= weight( n->left ) )
        erase( n->left, pos );
    else if ( pos == weight( n->left ) + 1 ) {
        n->priority = -1;//cout << "some" << endl;
        balance( n );
    } else
        erase( n->right, pos - weight( n->left ) - 1 );

    updateWeight( n );
}

void Treap::insert( Node * &n, int pos, int key, int priority )
{
    updateWeight( n );
    lazy( n );

    if ( n == NULL ) {
        assert( pos == 0 );
        n = new Node( key, priority );
    } else if ( pos <= weight( n->left ) )
        insert( n->left, pos, key, priority );
    else
        insert( n->right, pos - weight( n->left ) - 1, key, priority );

    balance( n );
}

int Treap::size( void )
{
    return weight( root );
}

void Treap::reverse( int p1, int p2 )
{
    p1 --;
    assert( p1 >= 0 && p1 < p2 && p2 <= size() );

    Node * t1, * aux, *t2, * t3;
    split( root, p1, t1, aux );
//    cout << "bar" << endl;
//    printNode( aux, cout );
//    cout << endl;
    split( aux, p2 - p1, t2, t3 );

    t2->rvs ^= 1;

//    cout << "foo" << endl;
    join( aux, t1, t2 );
//    cout << "some" << endl;
    join( root, aux, t3 );
}

void Treap::pop( int p1, int p2 )
{
    p1 --;
    assert( p1 >= 0 && p1 < p2 && p2 <= size() );

    Node * t1, * aux, *t2, * t3;
    split( root, p1, t1, aux );
    split( aux, p2 - p1, t2, t3 );

    join( root, t1, t3 );
}

int Treap::kth( int pos )
{
    assert( pos > 0 && pos <= size() );
    return search( root, pos );
}

void Treap::pop( int pos )
{
    assert( pos > 0 && pos <= size() );
    erase( root, pos );
}

void Treap::push( int pos, int key )
{
    assert( pos >= 0 && pos <= size() );
    insert( root, pos, key, rand() );
}

Treap::Treap( void )
{
    srand( time( NULL ) );
    root = NULL;
}

int main()
{
    ifstream fin( "secv8.in" );
    ofstream fout( "secv8.out" );

    int n, i, a, b, x;
    char ch;
    Treap secv;

    fin >> n >> x;

    for ( i = 0; i < n; i ++ ) {
        fin >> ch;
        if ( ch == 'I' ) {
            fin >> a >> b;
            secv.push( a - 1, b );
        } else if ( ch == 'A' ) {
            fin >> a;
            fout << secv.kth( a ) << '\n';
        } else if ( ch == 'R' ) {
            fin >> a >> b;
            secv.reverse( a, b );
        } else if ( ch == 'D' ) {
            fin >> a >> b;
            secv.pop( a, b );
        }
//        secv.print( fout );
    }

    secv.print( fout );

    fin.close();
    fout.close();

    return 0;
}