Cod sursa(job #2262835)

Utilizator algebristulFilip Berila algebristul Data 17 octombrie 2018 20:50:54
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.6 kb
#include <bits/stdc++.h>

using namespace std;

struct Node {
    int left = 0, right = 0;
    int cnt = 0;
    int lazy_reverse = 0;

    int val, pri;

    Node(int val_, int pri_) : val(val_), pri(pri_) {}
};

struct Treap {
    vector<Node> T;

    Treap() : T(1, Node(-1, -1)) {}

    int pull(int node) {
        if (!node) return node;

        T[node].cnt = T[T[node].left].cnt + T[T[node].right].cnt + 1;
        return node;
    }

    void push(int node) {
        if (!node) return;
        if (!T[node].lazy_reverse) return;

        T[T[node].left].lazy_reverse ^= T[node].lazy_reverse;
        T[T[node].right].lazy_reverse ^= T[node].lazy_reverse;
        swap(T[node].left, T[node].right);
        T[node].lazy_reverse = 0;

        pull(node);
    }

    int Join(int l, int r) {
        push(l);
        push(r);

        if (!l) return r;
        if (!r) return l;

        if (T[l].pri > T[r].pri) {
            T[l].right = Join(T[l].right, r);
            return pull(l);
        } else {
            T[r].left = Join(l, T[r].left);
            return pull(r);
        }
    }

    int index_of(int node) {
        return T[T[node].left].cnt;
    }

    pair<int, int> Split(int node, int key) {
        if (!node) return {0, 0};

        push(node);

        if (index_of(node) < key) {
            int l, r;
            tie(l, r) = Split(T[node].right, key - index_of(node) - 1);
            T[node].right = l;
            return {pull(node), r};
        } else {
            int l, r;
            tie(l, r) = Split(T[node].left, key);
            T[node].left = r;
            return {l, pull(node)};
        }
    }

    int One(int val) {
        int node = T.size();
        T.emplace_back(val, rand());
        return pull(node);
    }

    int root = 0;

    void Insert(int pos, int val) {
        int l, r;
        tie(l, r) = Split(root, pos);
        root = Join(l, Join(One(val), r));
    }

    int Access(int pos) {
        int l, m, r;
        tie(m, r) = Split(root, pos + 1);
        tie(l, m) = Split(m, pos);
        int val = T[m].val;
        root = Join(l, Join(m, r));
        return val;
    }

    void Reverse(int b, int e) {
        int l, m, r;
        tie(m, r) = Split(root, e + 1);
        tie(l, m) = Split(m, b);
        T[m].lazy_reverse ^= 1;
        root = Join(l, Join(m, r));
    }

    void Delete(int b, int e) {
        int l, m, r;
        tie(m, r) = Split(root, e + 1);
        tie(l, m) = Split(m, b);
        root = Join(l, r);
    }
    
    void Print(int node) {
        if (!node) return;
        push(node);
        Print(T[node].left);
        cout << T[node].val << ' ';
        Print(T[node].right);
    }

    void Print() {
        Print(root);
    }
};

int main() {
    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, r;
    Treap t;

    cin >> n >> r;
    for (int i = 1, x, y; i <= n; i++) {
        char op;
        cin >> op;
        switch (op) {
            case 'I':
                cin >> x >> y;
                --x;
                t.Insert(x, y);
                break;
            case 'A':
                cin >> x;
                --x;
                cout << t.Access(x) << '\n';
                break;
            case 'R':
                cin >> x >> y;
                --x; --y;
                t.Reverse(x, y);
                break;
            case 'D':
                cin >> x >> y;
                --x; --y;
                t.Delete(x, y);
                break;
            default:
                assert(false);
        }
    }

    t.Print();
    cout << '\n';

    return 0;
}