Cod sursa(job #1184898)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 14 mai 2014 14:56:40
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.23 kb
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;

const int INF = (1 << 30) + 1;

struct Node
{
    int nr_nodes, priority, key, rev;
    Node *left, *right;

    Node() {};

    Node( int c, int p, int k, int rv, Node* l, Node* r ) : nr_nodes(c), priority(p), key(k), rev(rv), left(l), right(r) {};
};

Node *T, *nil;

inline void lazy( Node *T )
{
    if ( T->rev )
    {
        swap( T->left, T->right );

        T->left->rev ^= 1; T->right->rev ^= 1;
        T->rev = 0;
    }
}

inline void update( Node *T )
{
    T->nr_nodes = T->left->nr_nodes + T->right->nr_nodes + 1;
}

inline void rotateRight( Node *&T )
{
    lazy( T ); lazy( T->left ); lazy( T->right );

    Node *tmp = T->left;
    T->left = tmp->right;
    tmp->right = T;
    T = tmp;

    update( T->right ); update( T );
}

inline void rotateLeft( Node *&T )
{
    lazy( T ); lazy( T->left ); lazy( T->right );

    Node *tmp = T->right;
    T->right = tmp->left;
    tmp->left = T;
    T = tmp;

    update( T->left ); update( T );
}

inline void balance( Node *&T )
{
    if ( T->left->priority > T->priority ) rotateRight( T );
    if ( T->right->priority > T->priority ) rotateLeft( T );
}

void insert( Node *&T, int pos, int key, int priority )
{
    if ( T == nil ) T = new Node( 1, priority, key, 0, nil, nil );
    else
    {
        lazy( T );

        if ( pos <= T->left->nr_nodes + 1 ) insert( T->left, pos, key, priority );
        else insert( T->right, pos - T->left->nr_nodes - 1, key, priority );

        balance( T ); update( T );
    }
}

int kth_element( Node *T, int pos )
{
    lazy( T );

    if ( T->left->nr_nodes + 1 == pos ) return T -> key;
    if ( T->left->nr_nodes >= pos ) return kth_element( T->left, pos );
    return kth_element( T->right, pos - T->left->nr_nodes - 1 );
}

void erase(Node *&T, int pos)
{
    lazy( T );

    if ( T->left->nr_nodes >= pos ) erase( T->left, pos );
    else
    {
        if ( T->left->nr_nodes + 1 < pos ) erase( T->right, pos - T->left->nr_nodes - 1 );
        else
        {
            if ( T->left == nil && T->right == nil )
            {
                delete T;
                T = nil;
                return;
            }

            if ( T->left->priority > T->right->priority )
                rotateRight( T ), erase( T->right, pos - T->left->nr_nodes - 1 );
            else
                rotateLeft( T ), erase( T->left, pos );
        }
    }

    update( T );
}

void split( Node *&T, Node *&T1, Node *&T2, int pos )
{
    insert( T, pos, 0, INF );
    T1 = T->left;
    T2 = T->right;
    delete T;
    T = nil;
}

void join( Node *&T, Node *T1, Node *T2 )
{
    T = new Node( 0, INF, 0, 0, T1, T2 );
    update( T );
    erase( T, T->left->nr_nodes + 1 );
}

void reverse( int i, int j )
{
    Node *tmp, *T1, *T2, *T3;

    split( T, tmp, T3, j + 1 );
    split( tmp, T1, T2, i );
    T2->rev = 1;
    join( tmp, T1, T2 );
    join( T, tmp, T3 );
}

void inorder( Node *T, ofstream &g )
{
    lazy( T );

    if ( T->left != nil) inorder( T->left, g );
    g << T->key << " ";
    if ( T->right != nil) inorder( T->right, g );
}

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

    srand( time( NULL ) );

    int N, rev, k, x, y;
    char oper;
    f >> N >> rev;

    T = nil = new Node(0, 0, 0, 0, NULL, NULL);
    nil -> left = nil -> right = nil;

    for (int i = 1; i <= N; ++i)
    {
        f >> oper;

        switch (oper)
        {
            case 'A':
            {
                f >> k;
                g << kth_element(T, k) << "\n";
                break;
            }
            case 'D':
            {
                f >> x >> y;
                for ( int j = x; j <= y; ++j ) erase(T, x);
                break;
            }
            case 'I':
            {
                f >> x >> y;
                insert(T, x, y, rand()%INF + 1);
                break;
            }
            case 'R':
            {
                f >> x >> y;
                reverse( x, y );
                break;
            }
        }
    }

    inorder(T, g);

    return 0;
}