Cod sursa(job #2043055)

Utilizator LucaSeriSeritan Luca LucaSeri Data 19 octombrie 2017 16:49:23
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.3 kb
#include <bits/stdc++.h>

using namespace std;

const int MOD = 666013;

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

struct treap{
    treap* st, *dr;
    int val;
    int g;
    int subarb;
    bool invers;
    treap(){
        st = NULL;
        dr = NULL;
        val = 0;
        g = 0;
        subarb = 1;
        invers = 0;
    }
    treap(treap*stanga, treap*dreapta, int v, int greutate, int sub){
        st = stanga;
        dr = dreapta;
        val = v;
        g = greutate;
        subarb = sub;
        invers = 0;
    }
};
treap *NILL, *root;
int ran(){return ((rand()<<14)+rand())%MOD;}

void refresh(treap*& node){
    assert(node != NULL);
    if(!node->invers) return;

    swap(node->st, node->dr);
    node->st->invers ^= 1;
    node->dr->invers ^= 1;
    node->invers = 0;
}
void recheck(treap*& node){
    node->subarb = 1 + node->st->subarb + node->dr->subarb;
}
void leftRotate(treap*& node){
    treap* aux = node->st;
    node->st = aux->dr;
    aux->dr = node;
    node = aux;
    recheck(node->dr);
    recheck(node);
}
void rightRotate(treap*& node){
    treap* aux = node->dr;
    node->dr = aux->st;
    aux->st = node;
    node = aux;
    recheck(node->st);
    recheck(node);
}
void balance(treap*& node){
    assert(node != NULL);
    if(node == NILL) assert(0);
    refresh(node);
    if(node->st->g > node->g) refresh(node->st), leftRotate(node);
    else if(node->dr->g > node->g) refresh(node->dr), rightRotate(node);
}
void erase_element(treap *& node, int poz){
    if(node == NILL) assert(0);
    refresh(node);

    if(node->st->subarb >= poz) erase_element(node->st, poz);
    else if(node->st->subarb + 1 < poz) erase_element(node->dr, poz-node->st->subarb-1);
    else{
        if(node->st == NILL && node->dr == NILL){
            node = NILL;
            return;
        }
        if(node->st->g > node->dr->g){
            refresh(node->st);
            leftRotate(node);
        }
        else{
            refresh(node->dr);
            rightRotate(node);
        }
        erase_element(node, poz);
    }

    if(node != NILL) recheck(node);
}

void baga(treap*& node, int poz, int val, int g){
    if(node == NILL){
        node = new treap(NILL, NILL, val, g, 1);
        return;
    }
    refresh(node);
    if(node->st->subarb >= poz) baga(node->st, poz, val, g);
    else baga(node->dr, poz-node->st->subarb-1, val, g);
    recheck(node);
    balance(node);
}
int access(treap*& node, int poz){
    refresh(node);
    if(node == NILL) assert(0);
    if(node->st->subarb + 1 == poz) return node->val;
    if(node->st->subarb >= poz) return access(node->st, poz);
    else return access(node->dr, poz-node->st->subarb-1);
}

void afis(treap*& node){
    assert(node != NULL);
    if(node == NILL) return;
    refresh(node);
    afis(node->st);
    g << node->val << ' ';
    afis(node->dr);
}
void split(treap*& node, int poz, treap*& t1, treap*& t2){
    baga(node, poz-1, 0, 200000000);
    t1 = node->st;
    t2 = node->dr;
    node = new treap;
    node = NILL;
}
void combine(treap*& node, treap*& t1, treap*& t2){
    node = new treap(t1, t2, 0, -1, 0);
    recheck(node);
    erase_element(node, t1->subarb+1);
}

int main(){
    int n;
    f >> n;
    int esential;
    f >> esential;
    f.get();

    NILL = new treap(NULL, NULL, 0, 0, 0);
    root = new treap;
    root = NILL;

    for(int i = 0; i < n; ++i){
        char c;
        f.get(c);
        if(c == 'I'){
            int k, e;
            f >> k >> e;
            baga(root, k-1, e, ran());
        }
        if(c == 'A'){
            int k; f >> k;
            g << access(root, k) << '\n';
        }
        if(c == 'R'){
            int a, b;
            f >> a >> b;
            treap *t1, *t2, *t3, *aux;

            split(root, a, t1, aux);
            split(aux, b-a+2, t2, t3);

            t2->invers ^= 1;
            combine(aux, t1, t2);
            combine(root, aux, t3);

        }
        if(c == 'D'){
            int a, b;
            f >> a >> b;

            treap *t1, *t2, *t3, *aux;
            split(root, a, t1, aux);
            split(aux, b-a+2, t2, t3);

            combine(root, t1, t3);
        }
        f.get();
    }

    afis(root);
    return 0;
}