Cod sursa(job #1175155)

Utilizator andreiiiiPopa Andrei andreiiii Data 24 aprilie 2014 16:25:41
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.54 kb
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <ctime>

using namespace std;

const int INF=0x3f3f3f3f;

struct Treap {
    int key, pry, size, rev;
    Treap *left, *right;
    Treap() {}
    Treap(int _key, int _pry, int _size, int _rev, Treap *_left, Treap *_right)
    {
        key=_key;
        pry=_pry;
        size=_size;
        rev=_rev;
        left=_left;
        right=_right;
    }
};

Treap *Root, *NIL;

void Write(Treap *node)
{
    if(node==NIL) return;

    Write(node->left);
    printf("%d ", node->key);
    Write(node->right);
}


void Update(Treap* &node)
{
    if(node!=NIL) node->size=node->left->size+node->right->size+1;
}

int get_rand()
{
    int ret=rand()*rand();
    if(ret<0) ret=-ret;
    if(!ret) ret++;
    return ret;
}

void Rev(Treap* &node)
{
    if(!node->rev) return;

    Treap *t=node->right;
    node->right=node->left;
    node->left=t;

    node->rev^=1;
    node->left->rev^=1;
    node->right->rev^=1;
}

void RotLeft(Treap* &node)
{
    Treap *t=node->left;
    node->left=t->right;
    t->right=node;
    node=t;

    Update(node->right);
    Update(node);
}

void RotRight(Treap* &node)
{
    Treap *t=node->right;
    node->right=t->left;
    t->left=node;
    node=t;

    Update(node->left);
    Update(node);
}

void Balance(Treap* &node)
{
    Rev(node);
    Rev(node->left);
    Rev(node->right);

    if(node->left->pry>node->pry) RotLeft(node);
    if(node->right->pry>node->pry) RotRight(node);
}

void Insert(Treap* &node, int poz, int key, int pry)
{
    if(node==NIL)
    {
        node=new Treap(key, pry, 1, 0, NIL, NIL);
        return;
    }

    Rev(node);

    if(node->left->size+1>=poz) Insert(node->left, poz, key, pry);
    else Insert(node->right, poz-node->left->size-1, key, pry);

    Balance(node);
    Update(node);
}

void Erase(Treap* &node, int poz)
{
    if(node==NIL) return;

    Rev(node);

    if(node->left->size+1==poz)
    {
        if(node->left==NIL&&node->right==NIL)
        {
            delete node;
            node=NIL;
            return;
        }

        Rev(node->left);
        Rev(node->right);

        if(node->left->pry>node->right->pry) RotLeft(node);
        else RotRight(node);
        Erase(node, poz);
    }
    else if(node->left->size>=poz) Erase(node->left, poz);
    else Erase(node->right, poz-node->left->size-1);

    Update(node);
}

int Find(Treap* &node, int poz)
{
    Rev(node);

    if(node->left->size>=poz) return Find(node->left, poz);
    if(node->left->size+1<poz) return Find(node->right, poz-node->left->size-1);
    return node->key;
}

void Split(Treap* &R, Treap* &Left, Treap* &Right, int poz)
{
    Insert(R, poz, 0, INF);

    //Write(R); printf("\n");

    Left=R->left;
    Right=R->right;
    delete R;
    R=NIL;
}

void Join(Treap* &R, Treap* &Left, Treap* &Right)
{
    R=new Treap(0, 0, Left->size+Right->size+1, 0, Left, Right);
    Erase(R, Left->size+1);
    //Write(R); printf("\n");
}

void Init()
{
    srand(time(0));
    Root=NIL=new Treap(0, 0, 0, 0, NULL, NULL);
    NIL->right=NIL->left=NIL;
}

int main()
{
    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);

    Init();

    int q, x, y;
    scanf("%d %d\n", &q, &x);

    while(q--)
    {
        char op;
        scanf("%c ", &op);
        if(op=='I')
        {
            scanf("%d %d\n", &x, &y);
            Insert(Root, x, y, get_rand());
        }
        else if(op=='A')
        {
            scanf("%d\n", &x);
            printf("%d\n", Find(Root, x));
        }
        else if(op=='D')
        {
            scanf("%d %d\n", &x, &y);

            Treap *S1, *S2, *S3, *t;

            Split(Root, t, S3, y+1);
            Split(t, S1, S2, x);

            //Write(S1); printf("\n"); Write(S2); printf("\n"); Write(S3); printf("\n");

            Join(Root, S1, S3);
        }
        else if(op=='R')
        {
            scanf("%d %d\n", &x, &y);

            Treap *S1, *S2, *S3, *t;

            Split(Root, t, S3, y+1);
            Split(t, S1, S2, x);

            //Write(S1); printf("\n"); Write(S2); printf("\n"); Write(S3); printf("\n");

            S2->rev^=1;

            Join(t, S1, S2);
            Join(Root, t, S3);
        }
        else if(op=='E')
        {
            scanf("%d\n", &x);
            Erase(Root, x);
        }
        /*Write(Root);
        printf("\n");*/
    }
    Write(Root);
    printf("\n");
}