Cod sursa(job #1150913)

Utilizator danalex97Dan H Alexandru danalex97 Data 23 martie 2014 18:15:56
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.3 kb
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
using namespace std;

ifstream F("secv8.in");
ofstream G("secv8.out");

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

struct treap
{
    int value,rev,priority,size;
    treap *left,*right;
    treap() {}
    treap(int priority,int value,int rev,int size,treap *left,treap *right)
    {
        this->priority = priority;
        this->value = value;
        this->rev = rev;
        this->left = left;
        this->right = right;
        this->size = size;
    }
};

/// fac un kind of lazy update ( adica doar cand cobor schimb rev-ul )

treap *_null;
treap *tree;
int n,m;

void init()
{
    srand(time(0));
    tree = _null = new treap(0,0,0,0,NULL,NULL);
}

void get_rev(treap* &t)
{
    if ( t->rev )
    {
        swap(t->left,t->right);
        t->rev = 0;
        t->left->rev ^= 1;
        t->right->rev ^=1;
    }
}

void update(treap *n)
{
    n->size = n->left->size + n->right->size + 1;
}

void rleft(treap* &z) // l->r
{
    treap* w = z->left;
    z->left = w->right;
    w->right = z;
    z = w;

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

void rright(treap* &w) // r->l
{
    treap* z = w->right;
    w->right = z->left;
    z->left = w;
    w = z;

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

void balance(treap* &n)
{
    if ( n->left->priority > n->priority )
    {
        get_rev(n);
        get_rev(n->left);
        rleft(n);
    }
    else
        if ( n->right->priority > n->priority )
        {
            get_rev(n);
            get_rev(n->right);
            rright(n);
        }
}

void insert(treap* &n,int pos,int priority,int value)
{
    if ( n == _null )
    {
        n = new treap(priority,value,value,1,_null,_null);
        return;
    }
    get_rev(n);
    if ( pos <= n->left->size+1 )
        insert(n->left,pos,priority,value);
    else
        insert(n->right,pos-(n->left->size+1),priority,value);
    balance(n);
    update(n);
}

void erase(treap *&t,int pos)
{
    get_rev(t);
    if ( pos == t->left->size+1  )
    {
        if ( t->left == _null && t->right == _null )
        {
            delete t;
            t = _null;
            return;
        }
        else if ( t->left->priority > t->right->priority )
        {
            get_rev(t->left);
            rleft(t);
            erase(t->right,pos-(t->left->size)-1);
        }
        else
        {
            get_rev(t->right);
            rright(t);
            erase(t->left,pos);
        }
    } else
    if ( t->left->size >= pos )
        erase(t->left,pos);
    else
        erase(t->right,pos-(t->left->size)-1);

    update(t);
}

int access(treap* n,int pos)
{
    get_rev(n);
    int a = n->left->size+1;
    if ( a > pos )
        return access(n->left,pos);
    else
        if ( a < pos )
            return access(n->right,pos-a);
    return n->value;
}

void split(treap* &n,int pos,treap* &a,treap* &b)
{
    insert(n,pos+1,infi,0);
    a = n->left;
    b = n->right;
    delete n;
    n = _null;
}

void join(treap* &n,treap *a,treap *b)
{
    treap* now = new treap(0,0,0,a->size+b->size+1,a,b);
    erase(now,a->size+1);
    n = now;
}

int main()
{
    init();
    tree->left = _null;
    tree->right = _null;
    F>>n>>m;

    for (int i=1;i<=n;++i)
    {
        char ch;
        F>>ch;
        if ( ch == 'I' )
        {
            int a,b;
            F>>a>>b;
            insert(tree,a,rand()+1,b);
        }
        if ( ch == 'A' )
        {
            int a;
            F>>a;
            G<<access(tree,a)<<'\n';
        }
        if ( ch == 'R' )
        {
            int a,b;
            F>>a>>b;

            treap *t1,*t2,*t3,*t;
            split(tree,a-1,t1,t);
            split(t,b-a+1,t2,t3);

            t2->rev ^= 1;

            join(t,t1,t2);
            join(tree,t,t3);
        }
        if ( ch == 'D' )
        {
            int a,b;
            F>>a>>b;
            for (int j=a;j<=b;++j)
                erase(tree,a);
        }
        /*cerr<<"step "<<i<<": ";
        for (int i=1;i<=tree->size;++i)
            cerr<<access(tree,i)<<' ';
        cerr<<'\n';*/
    }
    for (int i=1;i<=tree->size;++i)
        G<<access(tree,i)<<' ';
    G<<'\n';
}