Cod sursa(job #3185970)

Utilizator Constantin.Dragancea Constantin Constantin. Data 20 decembrie 2023 22:24:27
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.7 kb
#include <bits/stdc++.h>
using namespace std;

typedef struct Treap* Arbore;

Arbore nil;
mt19937 rnd;

struct Treap {
    int priority;
    int value;

    int size;
 
    bool lazy;

    Arbore left, right;

    Treap() {
        priority = rnd();
        value = 0;
        size = 1;
        lazy = false;
        left = right = nil;
    }

    void recalc() {
        size = left->size + right->size + 1;
    }

    // lazy the reverse
    void propagate(){
        if (lazy){
            swap(left, right);
            left->lazy ^= true;
            right->lazy ^= true;
            lazy = 0;
        }
    }
};

Arbore join(Arbore a, Arbore b){
    if (a == nil){
        return b;
    }
    if (b == nil){
        return a;
    }

    a->propagate();
    b->propagate();

    if (a->priority > b->priority){
        a->right = join(a->right, b);
        a->recalc();
        return a;
    }
    else {
        b->left = join(a, b->left);
        b->recalc();
        return b;
    }
}

pair <Arbore, Arbore> split_by_position(Arbore a, int k){
    if (a == nil)
        return {nil, nil};
    
    a->propagate();

    if (a->left->size >= k){
        auto [l, r] = split_by_position(a->left, k);

        a->left = r;
        a->recalc();

        return {l, a};
    }
    else {
        auto [l, r] = split_by_position(a->right, k - a->left->size - 1);

        a->right = l;
        a->recalc();

        return {a, r};
    }
    return {nil, nil};
}

Arbore insert(Arbore a, int value, int position){
    auto [l, r] = split_by_position(a, position);

    Arbore node = new Treap();
    node->value = value;

    return join(join(l, node), r);
}

pair <Arbore, int> get_value_at(Arbore a, int position){
    auto [l, r] = split_by_position(a, position);
    auto [r1, r2] = split_by_position(r, 1);

    int res = r1->value;
    
    Arbore tr = join(join(l, r1), r2);

    return {tr, res};
}

void dfs(Arbore a, vector<int>& res){
    if (a == nil)
        return;
    
    a->propagate();

    dfs(a->left, res);
    res.push_back(a->value);
    dfs(a->right, res);
}

Arbore reverse_subsequence(Arbore a, int left, int right){
    auto [l, r] = split_by_position(a, left);
    auto [r1, r2] = split_by_position(r, right - left + 1);

    r1->propagate();
    r1->lazy = true;

    return join(join(l, r1), r2);
}

Arbore delete_subsequence(Arbore a, int left, int right){
    auto [l, r] = split_by_position(a, left);
    auto [r1, r2] = split_by_position(r, right - left + 1);

    return join(l, r2);
}

int main(){
    ifstream cin("secv8.in");
    ofstream cout("secv8.out");

    rnd = mt19937(time(0));
    // srand(time(NULL));
    nil = new Treap();
    nil->size = 0;

    Arbore root = nil;

    int m, lol;
    cin >> m >> lol;

    while (m--){
        // cerr << "Elements in current step: ";
        // vector <int> v;
        // dfs(root, v);
        // for (auto i : v)
        //     cerr << i << ' ';
        // cerr << '\n';

        char c;
        int k, val;

        cin >> c;

        if (c == 'I'){
            cin >> k >> val;
            k--;
            root = insert(root, val, k);
        }
        else if (c == 'A'){
            cin >> k;
            k--;
            int ans;
            tie(root, ans) = get_value_at(root, k);

            cout << ans << '\n';
        }
        else if (c == 'R'){
            int l, r;
            cin >> l >> r;
            l--; r--;

            root = reverse_subsequence(root, l, r);
        }
        else { // c == 'D'
            assert(c == 'D');

            int l, r;
            cin >> l >> r;
            l--; r--;

            root = delete_subsequence(root, l, r);
        }
    }

    vector <int> arr;
    dfs(root, arr);

    for (int it: arr)
        cout << it << ' ';

    return 0;
}