Cod sursa(job #2024857)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 21 septembrie 2017 13:00:30
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.71 kb
#include <bits/stdc++.h>

using namespace std;

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

const int max_prior = INT_MAX;

int get_random(int lim)
{
    long long val = (rand() << 25LL) + (rand() << 20LL) + (rand() << 10LL) + (rand() ^ 7528529) + (rand() ^ 257982) + rand();
    val %= lim;
    if (val < 0) val += lim;
    return (int) val + 1;
}

struct treap {
    int val, prior, weight;
    bool inv;

    treap *left, *right;

    treap() {
        val = 0; prior = 0; weight = 0;
        inv = 0;

        left = NULL; right = NULL;
    }

    treap(int val, int prior, int weight, bool inv, treap *left, treap *right) {
        this -> val = val; this -> prior = prior; this -> weight = weight;
        this -> inv = inv;

        this -> left = left; this -> right = right;
    }
};

treap *null;

void treap_reweight(treap *&T) {
    if (T -> left != null) T -> left -> weight = T -> left -> left -> weight + T -> left -> right -> weight + 1;
    if (T -> right != null) T -> right -> weight = T -> right -> left -> weight + T -> right -> right -> weight + 1;
    T -> weight = T -> left -> weight + T -> right -> weight + 1;
}

void treap_lazy(treap *&T, int lvl) {
    if (T == null || lvl == 0) return;

    if (T -> left != null)
        T -> left -> inv ^= T -> inv;
    if (T -> right != null)
        T -> right -> inv ^= T -> inv;
    if (T -> inv == 1)
        swap(T -> left, T -> right), T -> inv = 0;

    treap_lazy(T -> left, lvl - 1);
    treap_lazy(T -> right, lvl - 1);
}

void treap_rotateL(treap *&T) {
    treap *aux = T -> left;
    T -> left = aux -> right;
    aux -> right = T;

    T = aux;
}

void treap_rotateR(treap *&T) {
    treap *aux = T -> right;
    T -> right = aux -> left;
    aux -> left = T;

    T = aux;
}

void treap_balance(treap *&T) {
    if (T -> left -> prior > T -> prior)
        treap_rotateL(T);
    else if (T -> right -> prior > T -> prior)
        treap_rotateR(T);

    treap_reweight(T);
}

void treap_insert(treap *&T, int pos, int val, int prior) {
    if (T == null) {
        T = new treap(val, prior, 1, 0, null, null);
        return;
    }

    treap_lazy(T, 2);

    if (pos <= T -> left -> weight + 1)
        treap_insert(T -> left, pos, val, prior);
    else treap_insert(T -> right, pos - T -> left -> weight - 1, val, prior);

    treap_balance(T);
}

void treap_erase(treap *&T) {
    if (T -> left == null && T -> right == null) {
        delete T; T = null;
        return;
    }

    treap_lazy(T, 2);

    if (T -> left -> prior > T -> right -> prior)
        treap_rotateL(T);
    else treap_rotateR(T);

    if (T -> left -> prior == -1)
        treap_erase(T -> left);
    else treap_erase(T -> right);

    treap_reweight(T);
}

void split(treap *&A, treap *&B, int pos) {
    treap_insert(A, pos, -1, max_prior);
    B = A -> right;
    A = A -> left;
}

void join(treap *&T, treap *&A, treap *&B) {
    T = new treap(0, -1, A -> weight + B -> weight + 1, 0, A, B);
    treap_erase(T);
}

void treap_erase(treap *&T, int low_pos, int high_pos) {
    treap *A = T, *B, *C;
    split(A, B, low_pos);
    split(B, C, high_pos + 1 - low_pos + 1);
    join(T, A, C);
}

void treap_reverse(treap *&T, int low_pos, int high_pos) {
    treap *A = T, *B, *C, *T_copy;
    split(A, B, low_pos);
    split(B, C, high_pos + 1 - low_pos + 1);
    B -> inv ^= 1;
    join(T, A, B); T_copy = T;
    join(T, T_copy, C);
}

int treap_access(treap *&T, int pos) {
    treap_lazy(T, 1);

    if (pos < T -> left -> weight + 1)
        return treap_access(T -> left, pos);
    else if (pos > T -> left -> weight + 1)
        return treap_access(T -> right, pos - T -> left -> weight - 1);

    return T -> val;
}

void treap_show(treap *&T) {
    if (T == null) return;
    treap_lazy(T, 1);

    treap_show(T -> left);
    fout << T -> val << ' ';
    treap_show(T -> right);
}

int main()
{
    treap *root = null = new treap(0, 0, 0, 0, NULL, NULL);

    int n, trash;
    fin >> n >> trash;

    for (int i = 1; i <= n; ++i) {
        char op; fin >> op;

        if (op == 'I') {
            int pos, val; fin >> pos >> val;
            treap_insert(root, pos, val, get_random(1e9));
        }
        else if (op == 'A') {
            int pos; fin >> pos;
            fout << treap_access(root, pos) << '\n';
        }
        else if (op == 'R') {
            int left, right; fin >> left >> right;
            treap_reverse(root, left, right);
        }
        else {
            int left, right; fin >> left >> right;
            treap_erase(root, left, right);
        }
    }

    treap_show(root); fout << '\n';

    return 0;
}