Cod sursa(job #2042475)

Utilizator LucaSeriSeritan Luca LucaSeri Data 18 octombrie 2017 18:08:08
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.21 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 = 0;
        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;
    }
};

class Trp{
    public:
    treap *NILL, *root;
    int random(){return ((rand()<<15)+rand())%MOD;}

    void Start(){
        NILL = new treap(NULL, NULL, 0, 0, 0);
        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){
        assert(node != NULL);
        if(node == NILL) return;
        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);
        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);
        }
        recheck(node);
    }

    void insert(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) insert(node->st, poz, val, g);
        else insert(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*& tr1, treap*& tr2){
        insert(node, poz-1, 0, 200000000);
        tr1 = node->st;
        tr2 = node->dr;
        node = new treap(NULL, NULL, 0, 0, 0);
        node = NILL;
    }
    void combine(treap*& node, treap*& tr1, treap*& tr2){
        node = new treap(tr1, tr2, 0, -1, 0);
        recheck(node);
        erase_element(node, tr1->subarb+1);
    }
    void reverse(int i, int j){
        treap *tr1, *tr2, *tr3, *aux;
        split(root, i, tr1, aux);
        split(aux, j-i+2, tr2, tr3);
        tr2->invers ^= 1;
        combine(aux, tr1, tr2);
        combine(root, aux, tr3);

        assert(root != NULL);
    }

}*T;

int main(){
    T = new Trp();
    T->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;
            T->insert(T->root, k-1, e, T->random());
        }
        if(c == 'A'){
            int k; f >> k;
            g << T->access(T->root, k) << '\n';
        }
        if(c == 'R'){
            int i, j;
            f >> i >> j;
            T->reverse(i, j);
        }
        if(c == 'D'){
            int i, j;
            f >> i >> j;

            treap *tr1, *tr2, *tr3, *aux;
            T->split(T->root, i, tr1, aux);
            T->split(aux, j-i+2, tr2, tr3);

            T->combine(T->root, tr1, tr3);
            assert(T->root != NULL);
        }
    }

    T->afis(T->root);
    return 0;
}