Cod sursa(job #1962003)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 11 aprilie 2017 15:12:12
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.98 kb
#include <bits/stdc++.h>

using namespace std;

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

const int inf = 2e9, vaal = (1<<15) - 1;

int MyRand()
{
    int x = ((rand() & vaal) << 15) ^ (rand() & vaal);
    x = max(x, -x);
    return x + 1;
}

struct T
{
    int key, prio, cnt;
    bool rev;
    T *left, *right;

    T(int Key, int Prio, T *Left, T *Right)
    {
        key = Key, prio = Prio, left = Left, right = Right, rev = 0;
        if(!(left==NULL && right==NULL))
            cnt = left->cnt + right->cnt + 1;
        else cnt = 0;
    }
} *root, *noo;
typedef pair< T*, T* > Pair;
int Q, REV, x, y;
char type;

void refresh_size(T *&t)
{
    if(t==noo) return;

    t->cnt = t->left->cnt + t->right->cnt + 1;
    if(t->rev)
    {
        swap(t->left, t->right);
        t -> rev = 0;
        t -> left -> rev ^= 1;
        t -> right -> rev ^= 1;
    }
}

void refresh_reversed(T *&t)
{
    if(t==noo || !t->rev) return;

    swap(t->left, t->right);
    t -> rev = 0;
    t -> left -> rev ^= 1;
    t -> right -> rev ^= 1;
}

void rotate_left(T *&t)
{
    T *aux = t->left;
    t->left = aux->right;
    aux->right = t;
    t = aux;

    refresh_size(t->right);
    refresh_size(t);
}

void rotate_right(T *&t)
{
    T *aux = t->right;
    t->right = aux->left;
    aux->left = t;
    t = aux;

    refresh_size(t->left);
    refresh_size(t);
}

void balance(T *&t)
{
    refresh_reversed(t);
    refresh_reversed(t->left);
    refresh_reversed(t->right);

    if(t->left->prio > t->prio) rotate_left(t);
        else if(t->right->prio > t->prio) rotate_right(t);
}

void Insert(T *&t, int pos, int Key, int Prio)
{
    if(t == noo)
    {
        t = new T(Key, Prio, noo, noo);
        return;
    }

    refresh_reversed(t);

    int nr = t -> left -> cnt;
    if(pos >= nr+1) Insert(t->right, pos-nr-1, Key, Prio);
        else Insert(t->left, pos, Key, Prio);

    refresh_size(t);
    balance(t);
}

int Acces(T *&t, int pos)
{
    refresh_reversed(t);

    int nr = t -> left -> cnt;
    if(nr+1 == pos) return t -> key;

    if(pos<=nr) return Acces(t->left, pos);
        else return Acces(t->right, pos-nr-1);
}

void Delete(T *&t, int pos)
{
    if(t->left == noo && t->right == noo)
    {
        delete t;
        t = noo;
        return;
    }

    refresh_reversed(t);

    int nr = t -> left -> cnt;
    if(nr+1 == pos)
    {
        if(t->left->prio > t->right->prio)
        {
            refresh_reversed(t->left);
            rotate_left(t);
            Delete(t->right, t->right->left->cnt + 1);
        }
        else
        {
            refresh_reversed(t->right);
            rotate_right(t);
            Delete(t->left, t->left->left->cnt + 1);
        }
    }
    else if(pos <= nr) Delete(t->left, pos);
        else Delete(t->right, pos-nr-1);

    refresh_size(t);
}

T* join(T* a, T* b, int pos)
{
    T* t = new T(0, inf, a, b);
    Delete(t, t->left->cnt + 1);
    return t;
}

Pair split(T* t, int pos)
{
    Insert(t, pos, 0, inf);
    Pair ans = {t->left, t->right};
    return ans;
}

void Reverse(int x, int y)
{
    Pair t1, t2;
    T *t;

    t1 = split(root, y);
    t2 = split(t1.first, x-1);

    t2.second -> rev ^= 1;
    t = join(t2.first, t2.second, x-1);

    root = join(t, t1.second, y);
}

void Print(T *t)
{
    if(t==noo) return;
    refresh_reversed(t);

    Print(t->left);
    fout << t->key << ' ';
    Print(t->right);
}

int main()
{
    fin >> Q >> REV;
    noo = root = new T(0, 0, NULL, NULL);
    srand(time(0));

    while(Q--)
    {
        fin >> type;
        if(type=='I')
        {
            fin >> x >> y;
            Insert(root, x-1, y, MyRand());
        }
        else if(type=='A')
        {
            fin >> x;
            fout << Acces(root, x) << '\n';
        }
        else if(type=='R')
        {
            fin >> x >> y;
            Reverse(x, y);
        }
        else
        {
            fin >> x >>  y;
            while(y>=x)
            {
                Delete(root, x);
                --y;
            }
        }
    }

    Print(root);

    return 0;
}