Cod sursa(job #2042006)

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

using namespace std;

const int MOD = 1e9 + 7;
int urca = MOD;

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

struct treap{
    treap* st, *dr;
    int val;
    int g;
    int subarb;
    bool invers;
    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;
        if(node->st != NILL) node->st->invers ^= 1;
        if(node->dr != NILL) node->dr->invers ^= 1;
        node->invers = 0;
        treap* temp = node->st;
        node->st = node->dr;
        node->dr = temp;
    }
    void recheck(treap*& node){
        assert(node != NULL);
        if(node == NILL) return;
        node->subarb = 1;
        node->subarb += node->st->subarb;
        node->subarb += node->dr->subarb;
    }
    void leftRotate(treap*& node){
        assert(node != NULL);
        treap* aux = node->st;
        node->st = aux->dr;
        aux->dr = node;
        node = aux;
        recheck(node->st);
        recheck(node);
    }
    void rightRotate(treap*& node){
        assert(node != NULL);
        treap* aux = node->dr;
        node->dr = aux->st;
        aux->st = node;
        node = aux;
        recheck(node->dr);
        recheck(node);
    }
    void balance(treap*& node){
        assert(node != NULL);
        if(node == NILL) return;
        recheck(node);
        refresh(node);
        if(node->st != NILL){
            refresh(node->st);
            recheck(node->st);
            if(node->st->g > node->g) leftRotate(node);
            recheck(node->st);
            recheck(node);
        }
        if(node->dr != NILL){
            refresh(node->dr);
            recheck(node->dr);
            if(node->dr->g > node->g) rightRotate(node);
            recheck(node->dr);
            recheck(node);
        }
        recheck(node);
    }
    void urca(treap*& node, int cheie, int poz){
        assert(node != NULL);
        if(node == NILL) return;
        refresh(node);
        recheck(node);
        if(poz == node->st->subarb+1){node->g = cheie; return;};
        if(node->st->subarb >= poz) urca(node->st, cheie, poz);
        else urca(node->dr, cheie, poz-node->st->subarb-1);
        balance(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){
                delete(node);
                node = NILL;
                return;
            }
            if(node->st->g > node->dr->g){
                refresh(node->st);
                leftRotate(node);
                recheck(node->dr);
            }
            else{
                refresh(node->dr);
                rightRotate(node);
                recheck(node->st);
            }
            erase_element(node, poz);
        }

        balance(node);
    }
    void reverse(int i, int j, int cheie){
        if(i==j) return;
        urca(root, cheie, j);
        urca(root, cheie-1, i);
        if(root->st->dr != NULL){
            root->st->dr->invers ^= 1;
            swap(root->val, root->st->val);
            balance(root->st);
            balance(root);
        }
        else{
            root->dr->st->invers ^= 1;
            swap(root->val, root->dr->val);
            balance(root->dr);
            balance(root);
        }
    }
    void insert(treap*& node, int poz, int val, int g){
        assert(node!=NULL);
        refresh(node);
        if(node == NILL){
            node = new treap(NILL, NILL, val, g, 0);
            return;
        }

        if(node->st->subarb+1 >= poz) insert(node->st, poz, val, g);
        else insert(node->dr, poz-node->st->subarb-1, val, g);
        balance(node);
    }
    int access(treap*& node, int poz){
        assert(node != NULL);
        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){
        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, 0, 2000000000);
        tr1 = node->st;
        tr2 = node->dr;
        //afis(node);
        //cout << "\nAM SPART IN "; afis(tr1); cout <<  " SI "; afis(tr2); cout << "\n";
        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);
    }

}*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, 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->afis(T->root);
            //cout << '\n';
            T->reverse(i, j, urca);
            //cout << '\n';
            //T->afis(T->root);
            ++urca;
        }
        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);
            ++urca;
        }
    }

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