Cod sursa(job #938163)

Utilizator darrenRares Buhai darren Data 11 aprilie 2013 23:00:28
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.25 kb
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <algorithm>

using namespace std;

const int INF = ((1LL << 31) - 1);

struct Tree
{
    int key, val, size;
    Tree *left, *right;
    bool rev;

    Tree()
    {
        size = 0;
        rev = false;
    }
    Tree(int _size, int _key, int _val, Tree *_left, Tree *_right)
    {
        size = _size;
        rev = false;
        key = _key;
        val = _val;
        left = _left;
        right = _right;
    }
};
Tree *R, *nil;

void get_size(Tree* T)
{
    T->size = T->left->size + T->right->size + 1;
}
void get_rev(Tree* T)
{
    if (T->rev == true)
    {
        Tree* aux = T->left;
        T->left = T->right;
        T->right = aux;

        T->rev = false;
        T->left->rev ^= 1;
        T->right->rev ^= 1;
    }
}
void rotate_left(Tree* &T)
{
    Tree *aux = T->left;
    T->left = aux->right;
    aux->right = T;
    T = aux;

    get_size(T->right);
    get_size(T);
}
void rotate_right(Tree* &T)
{
    Tree *aux = T->right;
    T->right = aux->left;
    aux->left = T;
    T = aux;

    get_size(T->left);
    get_size(T);
}
void balance(Tree* &T)
{
    if (T->left->val > T->val)
    {
        get_rev(T);
        get_rev(T->left);
        rotate_left(T);
    }
    if (T->right->val > T->val)
    {
        get_rev(T);
        get_rev(T->right);
        rotate_right(T);
    }
}
void insert(Tree* &T, int wh, int key, int val)
{
    if (T == nil)
    {
        T = new Tree(1, key, val, nil, nil);
        return;
    }

    get_rev(T);
    if (1 + T->left->size >= wh) insert(T->left, wh, key, val);
    else                         insert(T->right, wh - T->left->size - 1, key, val);

    get_size(T);
    balance(T);
}
void erase(Tree* &T, int wh)
{
    get_rev(T);
    if (1 + T->left->size > wh)
    {
        erase(T->left, wh);
        get_size(T);
    }
    else if (1 + T->left->size < wh)
    {
        erase(T->right, wh - T->left->size - 1);
        get_size(T);
    }
    else
    {
        if (T->left == nil && T->right == nil)
        {
            delete T;
            T = nil;
        }
        else
        {
            if (T->left->val > T->right->val)
            {
                get_rev(T->left);
                rotate_left(T);
                erase(T->right, 1 + T->right->left->size);
                get_size(T);
            }
            else
            {
                get_rev(T->right);
                rotate_right(T);
                erase(T->left, 1 + T->left->left->size);
                get_size(T);
            }
        }
    }
}
int access(Tree* T, int wh)
{
    get_rev(T);
    if (1 + T->left->size == wh) return T->key;
    if (1 + T->left->size > wh) return access(T->left, wh);
    return access(T->right, wh - T->left->size - 1);
}
void split(Tree* T, int wh, Tree* &T1, Tree* &T2)
{
    insert(T, wh + 1, 0, INF);
    T1 = T->left;
    T2 = T->right;
    delete T;
}
void join(Tree* T1, Tree* T2, Tree* &T)
{
    Tree* Tn = new Tree(1 + T1->size + T2->size, 0, 0, T1, T2);
    erase(Tn, 1 + T1->size);
    T = Tn;
}

int N, useless;

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

    srand(time(0));
    R = nil = new Tree(0, 0, 0, 0, 0);

    fin >> N >> useless;

    char opnow;
    int p1, p2;

    for (int i = 1; i <= N; ++i)
    {
        fin >> opnow;
        if (opnow == 'I')
        {
            fin >> p1 >> p2;
            insert(R, p1, p2, rand() + 1);
        }
        else if (opnow == 'A')
        {
            fin >> p1;
            fout << access(R, p1) << '\n';
        }
        else if (opnow == 'R')
        {
            fin >> p1 >> p2;

            Tree *T1, *T2, *T3, *Taux;
            split(R, p1 - 1, T1, Taux);
            split(Taux, (p2 - p1 + 1), T2, T3);

            T2->rev ^= 1;

            join(T1, T2, Taux);
            join(Taux, T3, R);
        }
        else
        {
            fin >> p1 >> p2;
            for (int i = p1; i <= p2; ++i)
                erase(R, p1);
        }
    }

    for (int i = 1; i <= R->size; ++i)
        fout << access(R, i) << ' ';
    fout << '\n';

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