Cod sursa(job #1781121)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 16 octombrie 2016 18:12:01
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.62 kb
#include <fstream>
#include <string>
#include <ctime>
#include <cstdlib>

using namespace std;

ifstream fin ("secv8.in"); ofstream fout ("secv8.out");

const int nmax = 250000;
const int inf = (1 << 30) - 1 + (1 << 30);

struct Treap_node{
    int cate, inv, val, p;
    Treap_node *left, *right;

    Treap_node() {
        cate = inv = 0;
        left = right = NULL;
    }
} *root, *NIL;

typedef pair<Treap_node*, Treap_node*> ptt;

Treap_node* recalc (Treap_node *nod) {
    nod -> cate = nod -> left -> cate + nod -> right -> cate + 1;
    return nod;
}

void propagate (Treap_node* &nod) {
    if (nod -> inv == 0) return ;

    swap(nod -> left, nod -> right);

    nod -> left -> inv ^= 1;
    nod -> right -> inv ^= 1;

    nod -> inv = 0;
}

Treap_node* rotate_left (Treap_node *nod) {
    propagate( nod );
    propagate(nod -> left);
    Treap_node *aux = nod -> left;
    nod -> left = aux -> right;
    aux -> right = nod;
    nod = recalc( nod );
    aux = recalc( aux );
    return aux;
}

Treap_node* rotate_right (Treap_node *nod) {
    propagate( nod );
    propagate(nod -> right);
    Treap_node *aux = nod -> right;
    nod -> right = aux -> left;
    aux -> left = nod;
    nod = recalc( nod );
    aux = recalc( aux );
    return aux;
}

Treap_node* balance (Treap_node *nod) {
    if (nod -> p < (nod -> left -> p)) {
        return rotate_left( nod );
    } else if (nod -> p < (nod -> right -> p)) {
        return rotate_right( nod );
    } else {
        return recalc( nod );
    }
}

Treap_node* insert (Treap_node *nod, int pos, int val, int p) {
    if (nod == NIL) {
        nod = new Treap_node();
        nod -> left = nod -> right = NIL;
        nod -> val = val, nod -> cate = 1, nod -> p = p;
        return nod;
    } else {
        propagate( nod );
        if (pos <= nod -> left -> cate + 1) {
            nod -> left = insert(nod -> left, pos, val, p);
        } else {
            nod -> right = insert(nod -> right, pos - (nod -> left -> cate + 1), val, p);
        }
    }
    return nod = balance( nod );
}

Treap_node* erase (Treap_node *nod, int pos) {
    propagate( nod );
    if (nod -> left == NIL && nod -> right == NIL) {
        delete nod;
        return NIL;
    } else if (pos == nod -> left -> cate + 1) {
        if (nod -> left == NIL || (nod -> left -> p) < (nod -> right -> p)) {
            nod = rotate_right( nod );
            nod -> left = erase(nod -> left, pos);
        } else {
            nod = rotate_left( nod );
            nod -> right = erase(nod -> right, pos - (nod -> left -> cate + 1));
        }
    } else {
        if (pos < nod -> left -> cate + 1) {
            nod -> left = erase(nod -> left, pos);
        } else {
            nod -> right = erase(nod -> right, pos - (nod -> left -> cate + 1));
        }
    }
    return nod = balance( nod );
}

int query (Treap_node *nod, int pos) {
    propagate( nod );
    if (nod -> left -> cate + 1 == pos) {
        return nod -> val;
    } else if (pos < nod -> left -> cate + 1) {
        return query(nod -> left, pos);
    } else {
        return query(nod -> right, pos - (nod -> left -> cate + 1));
    }
}

ptt split (Treap_node *nod, int pos) {
    nod = insert(nod, pos, -1, inf);
    return make_pair(nod -> left, nod -> right);
}

Treap_node* join (Treap_node *x, Treap_node *y) {
    Treap_node *ans;
    ans = new Treap_node();
    ans -> val = -1, ans -> p = 0;
    ans -> left = x, ans -> right = y;
    ans = recalc( ans );
    ans = erase(ans, x -> cate + 1);
    return ans;
}

int main() {
    int n, tip;
    fin >> n >> tip;

    NIL = new Treap_node();
    NIL -> p = -1;
    NIL -> left = NIL -> right = NIL;

    root = new Treap_node();
    root = NIL;

    srand( time(0) );

    for (int i = 1; i <= n; ++ i) {
        string op;
        int x, y;
        fin >> op >> x;

        if (op == "A") {
            fout << query(root, x) << "\n";
        } else {
            fin >> y;
            if (op == "I") {
                root = insert(root, x, y, rand() % (inf - 1) + 1);
            } else {
                Treap_node *st, *mij, *dr;
                ptt aux = split(root, x);
                st = aux.first;

                aux = split(aux.second, y - x + 2);
                mij = aux.first, dr = aux.second;

                if (op == "R") {
                    mij -> inv ^= 1;
                    root = join(st, mij);
                    root = join(root, dr);
                } else {
                    root = join(st, dr);
                }
            }
        }
    }

    while (root -> cate > 0) {
        fout << query(root, 1) << " ";
        root = erase(root, 1);
    }
    fout << "\n";

    fin.close();
    fout.close();
    return 0;
}