Cod sursa(job #2593327)

Utilizator IulianOleniucIulian Oleniuc IulianOleniuc Data 3 aprilie 2020 15:43:52
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.55 kb
#include <bits/stdc++.h>
using namespace std;

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

class Treap {
  private:
    struct Node {
        int val, pri, l = 0, r = 0, cnt = 0, rev = 0;
        Node(int val, int pri) : val(val), pri(pri) { }
    };

    int root = 0;
    vector<Node> tree = vector<Node>(1, Node(-1, -1));

    int update(int node) {
        tree[node].cnt = tree[tree[node].l].cnt + tree[tree[node].r].cnt + 1;
        return node;
    }

    void shift(int node) {
        if (node && tree[node].rev) {
            tree[tree[node].l].rev ^= 1; swap(tree[tree[node].l].l, tree[tree[node].l].r);
            tree[tree[node].r].rev ^= 1; swap(tree[tree[node].r].l, tree[tree[node].r].r);
            tree[node].rev = 0;
        }
    }

    int join(int l, int r) {
        shift(r); if (!l) return r;
        shift(l); if (!r) return l;
        if (tree[l].pri > tree[r].pri) {
            tree[l].r = join(tree[l].r, r);
            return update(l);
        } else {
            tree[r].l = join(l, tree[r].l);
            return update(r);
        }
    }

    pair<int, int> split(int node, int key) {
        if (!node)
            return make_pair(0, 0);
        shift(node);
        int cnt = tree[tree[node].l].cnt;
        if (key < cnt) {
            int l, r; tie(l, r) = split(tree[node].l, key);
            tree[node].l = r;
            return make_pair(l, update(node));
        } else {
            int l, r; tie(l, r) = split(tree[node].r, key - cnt - 1);
            tree[node].r = l;
            return make_pair(update(node), r);
        }
    }

    int addNode(int val) {
        tree.emplace_back(val, rand());
        return update(tree.size() - 1);
    }

    tuple<int, int, int> slice(int node, int a, int b) {
        int l, m, r;
        tie(m, r) = split(node, b);
        tie(l, m) = split(m, a - 1);
        return make_tuple(l, m, r);
    }

    void dfs(int node, vector<int>& vec) {
        if (node) {
            dfs(tree[node].l, vec);
            vec.push_back(tree[node].val);
            dfs(tree[node].r, vec);
        }
    }

  public:
    void insert(int key, int val) {
        int l, r; tie(l, r) = split(root, key - 1);
        root = join(join(l, addNode(val)), r);
    }

    int getKth(int key) {
        int l, m, r; tie(l, m, r) = slice(root, key, key);
        root = join(join(l, m), r);
        return tree[m].val;
    }

    void reverse(int a, int b) {
        int l, m, r; tie(l, m, r) = slice(root, a, b);
        tree[m].rev = 1;
        swap(tree[m].l, tree[m].r);
        root = join(join(l, m), r);
    }

    void erase(int a, int b) {
        int l, m, r; tie(l, m, r) = slice(root, a, b);
        root = join(l, r);
    }

    vector<int> getAll() {
        vector<int> ans;
        for (int i = 0; i < tree[root].cnt; i++)
            ans.push_back(getKth(i));
        return ans;
    }
};

int main() {
    Treap treap;
    srand(time(nullptr));

    int q, mlc; fin >> q >> mlc;
    for (int i = 0; i < q; i++) {
        char type; fin >> type;
        if (type == 'I') {
            int pos, val; fin >> pos >> val;
            treap.insert(pos - 1, val);
        } else if (type == 'A') {
            int pos; fin >> pos;
            fout << treap.getKth(pos - 1) << '\n';
        } else if (type == 'R') {
            int l, r; fin >> l >> r;
            treap.reverse(l - 1, r - 1);
        } else {
            int l, r; fin >> l >> r;
            treap.erase(l - 1, r - 1);
        }
    }

    auto ans = treap.getAll();
    for (int val : ans)
        fout << val << ' ';
    fout << '\n';

    fout.close();
    return 0;
}