Cod sursa(job #1072032)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 3 ianuarie 2014 20:40:22
Problema Secv8 Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.05 kb
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;

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

struct Node
{
    int cnt, pri, key;
    bool rev;
    Node *left, *right;

    Node() {};

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

Node *T, *nil;

void lazy(Node *T)
{
    if (T -> rev)
    {
        Node *aux = T -> left;
        T -> left = T -> right;
        T -> right = aux;

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

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

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

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

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

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

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

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

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

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

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

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

            if (T->left->pri > T->right->pri)
            {
                rotateRight(T);
                erase(T->right, pos - T->left->cnt - 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->cnt + 1);
}

void reverse( int x, int y )
{
    Node *tmp, *T1, *T2, *T3;

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

void inorder( Node *nod, ofstream &f )
{
    lazy( nod );
    if ( nod->left != nil ) inorder( nod->left, f );
    f << nod->key << " ";
    if ( nod->right != nil ) inorder( nod->right, f );
}

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

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

    srand( time( NULL) );

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

    f >> N >> e;

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

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

             insert( T, k, e, rand() + 1 );
        }

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

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

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

           for ( int k = i; k <= j; ++k )
                    erase( T, i );
        }

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

            reverse( i, j );
        }
    }

    inorder( T, g );

    return 0;
}