Cod sursa(job #3150268)

Utilizator rastervcrastervc rastervc Data 15 septembrie 2023 20:01:25
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.4 kb
#include <bits/stdc++.h>

using namespace std;

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

struct Treap {
    Treap *left, *right;
    int val, priority, size;
    bool rev;

    inline Treap(int val)
        : left(), right(), val(val), priority(rand()), size(1), rev(false) {}

    inline ~Treap() {
        delete left;
        delete right;
    }
};

inline int size(Treap *treap) { return treap ? treap->size : 0; };

inline void push_up(Treap *treap) {
    if (treap) treap->size = 1 + size(treap->left) + size(treap->right);
}

inline void push_down(Treap *treap) {
    if (treap && treap->rev) {
        treap->rev ^= 1;
        swap(treap->left, treap->right);
        if (treap->left) treap->left->rev ^= 1;
        if (treap->right) treap->right->rev ^= 1;
    }
}

inline pair<Treap *, Treap *> split(Treap *treap, int key) {
    if (!treap) return make_pair(nullptr, nullptr);
    push_down(treap);
    if (key <= size(treap->left)) {
        const auto[left, right] = split(treap->left, key);
        treap->left = right;
        push_up(treap);
        return make_pair(left, treap);
    } else {
        const auto[left, right] = split(treap->right, key - 1 - size(treap->left));
        treap->right = left;
        push_up(treap);
        return make_pair(treap, right);
    }
}

inline Treap * merge(Treap *treap1, Treap *treap2) {
    if (!treap1 || !treap2)
        return treap1 ? treap1 : treap2;
    push_down(treap1);
    push_down(treap2);
    if (treap1->priority >= treap2->priority) {
        treap1->right = merge(treap1->right, treap2);
        push_up(treap1);
        return treap1;
    } else{
        treap2->left = merge(treap1, treap2->left);
        push_up(treap2);
        return treap2;
    }
}

inline Treap * insert(Treap *treap, int index, int val) {
    auto[left, right] = split(treap, index - 1);
    return merge(merge(left, new Treap(val)), right);
}

inline Treap * erase(Treap *treap, int l, int r) {
    auto[left0, right] = split(treap, r);
    auto[left, middle] = split(left0, l - 1);
    return merge(left, right);
}

inline Treap * reverse(Treap *treap, int l, int r) {
    auto[left0, right] = split(treap, r);
    auto[left, middle] = split(left0, l - 1);
    middle->rev ^= 1;
    return merge(merge(left, middle), right);
}

inline int get(Treap *&treap, int index) {
    auto[left0, right] = split(treap, index);
    auto[left, middle] = split(left0, index - 1);
    const int val = middle->val;
    treap = merge(merge(left, middle), right);
    return val;
}

inline void print(Treap *treap) {
    if (!treap) return;
    push_down(treap);
    print(treap->left);
    fout << treap->val << ' ';
    print(treap->right);
}

int main() {
    srand(time(NULL));
    Treap *treap = nullptr;

    int N, _;
    fin >> N >> _;

    for (int i = 0; i < N; ++i) {
        char op;
        int a, b;
        fin >> op;
        if (op == 'I') {
            fin >> a >> b;
            treap = insert(treap, a, b);
        } else if (op == 'A') {
            fin >> a;
            fout << get(treap, a) << '\n';
        } else if (op == 'R') {
            fin >> a >> b;
            treap = reverse(treap, a, b);
        } else {
            fin >> a >> b;
            treap = erase(treap, a, b);
        }
    }

    print(treap);

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