Cod sursa(job #2846609)

Utilizator Cosmin2004_InfoMoldoveanu Cosmin Cosmin2004_Info Data 9 februarie 2022 13:31:34
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.05 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("secv8.in");
ofstream fout("secv8.out");
unsigned seed = chrono :: system_clock :: now().time_since_epoch().count();
mt19937 rng(seed);
struct treap {
    treap *left, *right;
    int val, priority, subtree_size;
    bool mirror;
    friend int size(treap* t) { return t ? t -> subtree_size : 0; }
    friend void update(treap* t) { t -> subtree_size = 1 + size(t -> left) + size(t -> right); }
    friend void apply(treap* t) { if(t) { t -> mirror ^= true; swap(t -> left, t -> right); } }
    friend void prop(treap* t) {
        if(t && t -> mirror) {
            //fout << "Propping " << t -> val << " of size " << size(t) << "\n";
            t -> mirror = false;
            apply(t -> left);
            apply(t -> right);
        }
    }
    treap(int val) : left(NULL), right(NULL), val(val), priority(rng()), subtree_size(1), mirror(false) {}
};
treap* root = NULL;

array <treap*, 2> split(treap* t, int key) {
    if(!t) return {NULL, NULL};
    prop(t);
    if(key <= size(t -> left)) {
        auto [res_left, res_right] = split(t -> left, key);
        t -> left = res_right;
        update(t);
        return {res_left, t};
    } else {
        auto [res_left, res_right] = split(t -> right, key - size(t -> left) - 1);
        t -> right = res_left;
        update(t);
        return {t, res_right};
    }
}

treap* merge(treap* l, treap* r) {
    if(!l) return r;
    if(!r) return l;
    prop(l); prop(r);
    if(l -> priority <= r -> priority) {
        r -> left = merge(l, r -> left);
        update(r);
        return r;
    } else {
        l -> right = merge(l -> right, r);
        update(l);
        return l;
    }
}

void insert(int pos, int val) {
    auto [l, r] = split(root, pos);
    root = merge(l, merge(new treap(val), r));
}

void erase(int lpos, int rpos) {
    auto [l, r1] = split(root, lpos);
    auto [l1, r] = split(r1, rpos - lpos);
    root = merge(l, r);
}

int access(treap* t, int key) {
    prop(t);
    if(size(t -> left) >= key) return access(t -> left, key);
    if(size(t -> left) + 1 == key) return t -> val;
    return access(t -> right, key - size(t -> left) - 1);
}

void reverse(int lpos, int rpos) {
    auto [l, r1] = split(root, lpos);
    auto [l1, r] = split(r1, rpos - lpos);
    apply(l1);
    root = merge(l, merge(l1, r));
}

void print(treap* t) {
    prop(t);
    if(!t) return;
    print(t -> left);
    fout << t -> val << " ";
    print(t -> right);
}

int main()
{
    int n, m, x, y; char ch;
    fin >> n >> m;
    for(int i = 1; i <= n; i++) {
        fin >> ch >> x;
        if(ch == 'I') {
            fin >> y;
            insert(x - 1, y);
        } else if(ch == 'R') {
            fin >> y;
            reverse(x - 1, y);
        } else if(ch == 'A') {
            fout << access(root, x) << "\n";
        } else if(ch == 'D') {
            fin >> y;
            erase(x - 1, y);
        }
        //print(root); fout << "\n";
    }
    print(root);
    return 0;
}