Cod sursa(job #2043859)

Utilizator LucaSeriSeritan Luca LucaSeri Data 20 octombrie 2017 17:37:28
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.23 kb
#include <bits/stdc++.h>

using namespace std;

const int MOD = 1e8 + 7;
const int inf = 1e9;

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

struct treap{
    int sub, v, g;
    bool inv;
    treap *st, *dr;
    treap(treap* stanga, treap* dreapta, int subarb, int val, int greutate, bool invers){
        st = stanga;
        dr = dreapta;
        sub = subarb;
        v = val;
        g = greutate;
        inv = invers;
    }
}*root, *NILL, *t1, *t2, *t3, *aux;
int gen(){return ((rand()<<10)+rand())%MOD + 1; }
void recount(treap*& node){if(node == NILL) return; node->sub = node->st->sub + node->dr->sub + 1;}
void check(treap*& node){
    assert(node != NULL);
    if(node == NILL) return;
    if(!(node->inv)) return;
    swap(node->st, node->dr);
    if(node->st!=NILL) node->st->inv ^= 1;
    if(node->dr!=NILL) node->dr->inv ^= 1;
    node->inv = 0;
}
void roleft(treap*& node){
    assert(node != NULL);
    check(node->st);
    treap* aux = node->st;
    node->st = aux->dr;
    aux->dr = node;
    node = aux;
    recount(node->dr);
    recount(node->st);
    recount(node);
    assert(node != NULL);
}
void roright(treap*& node){
    assert(node != NULL);
    check(node->dr);
    treap* aux = node->dr;
    node->dr = aux->st;
    aux->st = node;
    node = aux;
    recount(node->st);
    recount(node->dr);
    recount(node);
    assert(node != NULL);
}
void balance(treap*& node){
    assert(node != NULL);
    if(node == NILL) return;
    if(node->st != NILL && node->st-> g > node-> g) roleft(node);
    if(node->st != NILL) recount(node->st);
    if(node->dr != NILL && node->dr-> g > node-> g) roright(node);
    if(node->dr != NILL) recount(node->dr);
    recount(node);
}

void baga(treap*& node, int poz, int val, int g){
    assert(node != NULL);
    if(node == NILL){
        node = new treap(NILL, NILL, 1, val, g, 0);
        return;
    }
    check(node);
    if(node->st->sub >= poz) baga(node->st, poz, val, g);
    else baga(node->dr, poz-node->st->sub-1, val, g);
    recount(node);
    balance(node);
}
void sterge(treap*& node, int poz){
    assert(node != NULL);
    check(node);
    if(node->st->sub >= poz) sterge(node->st, poz);
    else if(node->st->sub + 1 < poz) sterge(node->dr, poz - node->st->sub- 1);
    else{
        if(node == NILL) return;
        if(node->st == NILL && node->dr == NILL){
            delete node;
            node = NILL;
            return;
        }
        if(node->st->g > node->dr->g && node->st != NILL){
            check(node->st);
            roleft(node);
        }
        else if(node->dr != NILL){
            check(node->dr);
            roright(node);
        }
        sterge(node, poz);
    }

    recount(node);
}
int gaseste(treap*& node, int poz){
    assert(node != NULL);
    if(node == NILL) return -1;
    check(node);
    if(node->st->sub+1 == poz) return node->v;
    if(node->st->sub >= poz) return gaseste(node->st, poz);
    return gaseste(node->dr, poz-node->st->sub-1);
}

void split(treap*& node, treap*& t1, treap*& t2, int poz){
    assert(node != NULL);
    baga(node, poz, 0, inf);
    t1 = node->st;
    t2 = node->dr;
    delete node;
    node = NILL;
}

void join(treap *& temp, treap *&a, treap *&b){
    assert(temp != NULL);
    temp = new treap(a, b, a->sub+b->sub+1, 0, -1, 0);
    sterge(temp, temp->st->sub+1);
}
void scrie(treap*& node){
    assert(node != NULL);
    if(node == NILL) return;
    scrie(node->st);
    g << node->v << ' ';
    scrie(node->dr);
}
int main(){
    int n, x;
    f >> n >> x;
    NILL = new treap(NULL, NULL, 0, 0, 0, 0);
    root = NILL;
    while(n--){
        char cd;
        int a, b;
        f >> cd;
        f >> a;
        if(cd != 'A') f >> b;
        if(cd == 'I') baga(root, a-1, b, gen());
        if(cd == 'A') g << gaseste(root, a) << '\n';
        if(cd == 'R'){
            split(root, aux, t3, b);
            split(aux, t1, t2, a-1);
            t2->inv ^= 1;
            join(aux, t1, t2);
            join(root, aux, t3);
        }
        if(cd == 'D'){
            split(root, aux, t3, b);
            split(aux, t1, t2, a-1);
            join(root, t1, t3);
        }
    }

    scrie(root);
}