Cod sursa(job #2042617)

Utilizator LucaSeriSeritan Luca LucaSeri Data 18 octombrie 2017 20:55:54
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.57 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(){
        this->st = NULL;
        this->dr = NULL;
        this->val = 0;
        this->g = 0;
        this->subarb = 1;
        this->invers = 0;
    }
    treap(treap*stanga, treap*dreapta, int val, int greutate, int subarb){
        this->st = stanga;
        this->dr = dreapta;
        this->val = val;
        this->g = greutate;
        this->subarb = subarb;
        this->invers = 0;
    }
};
treap *NILL, *root;
int ran(){return ((rand()<<15)+rand())%MOD;}

void Start(){
    NILL = new treap(NULL, NULL, 0, 0, 0);
    root = new treap;
    root = NILL;
}
void refresh(treap*& node){
    assert(node != NULL);
    if(node == NILL || node->invers == false) return;
    node->st->invers ^= 1;
    node->dr->invers ^= 1;
    node->invers = 0;
    swap(node->st, node->dr);
}
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) return;
    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){
    assert(node != NULL);
    if(node == NILL) return;
    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){
    assert(node!=NULL);
    assert(poz >= 0);
    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){
    assert(node != NULL);
    assert(poz >= 0);
    refresh(node);
    if(node == NILL) return -1;
    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(){
    Start();
    int n;
    f >> n;
    int esential;
    f >> esential;
    for(int i = 0; i < n; ++i){
        char c;
        f >> 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;
            aux = new treap;
            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;
            aux = new treap;
            split(root, a, t1, aux);
            split(aux, b-a+2, t2, t3);

            combine(root, t1, t3);
        }
    }

    afis(root);
    return 0;
}