Cod sursa(job #2844924)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 6 februarie 2022 12:29:04
Problema Secv8 Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.27 kb
#include <bits/stdc++.h>

using namespace std;

inline void Open(const string Name) {
    #ifndef ONLINE_JUDGE
        (void)!freopen((Name + ".in").c_str(), "r", stdin);
        (void)!freopen((Name + ".out").c_str(), "w", stdout);
    #endif
}

const int MOD = 805306457;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct treapNode {
    int key, prior, cnt;
    bool rev;
    treapNode *l, *r;
};

using ptt = pair <treapNode*, treapNode*>;
treapNode *emptyNode = new treapNode{-1, -1, 0, 0, nullptr, nullptr};
treapNode *root = emptyNode;

void push(treapNode *node) {
    if(node != emptyNode && node -> rev) {
        swap(node -> l, node -> r);
        node -> l -> rev ^= 1;
        node -> r -> rev ^= 1;
        node -> rev = 0;
    }
}

void update(treapNode *node) {
    if(node != emptyNode) {
        node -> cnt = 1 + node -> l -> cnt + node -> r -> cnt;
    }
}

ptt split(treapNode *node, int k) {
    if(node == emptyNode)
        return {emptyNode, emptyNode};

    push(node);
    if(node -> l -> cnt < k) {
        ptt p = split(node -> r, k - node -> l -> cnt - 1);
        node -> r = p.first;
        update(node);
        return {node, p.second};
    }

    ptt p = split(node -> l, k);
    node -> l = p.second;
    update(node);
    return {p.first, node};
}

treapNode *join(treapNode *a, treapNode *b) {
    if(a == emptyNode)
        return b;
    if(b == emptyNode)
        return a;

    push(a), push(b);
    if(a -> prior > b -> prior) {
        a -> r = join(a -> r, b);
        update(a);
        return a;
    }

    b -> l = join(a, b -> l);
    update(b);
    return b;
}

treapNode *ins(treapNode *node, int k, treapNode *newNode) {
    ptt p = split(node, k - 1);
    return join(join(p.first, newNode), p.second);
}

treapNode *rem(treapNode *node, int l, int r) {
    ptt p1 = split(node, l - 1);
    ptt p2 = split(p1.second, r - l + 1);
    return join(p1.first, p2.second);
}

treapNode *rev(treapNode *node, int l, int r)  {
    ptt p1 = split(node, l - 1);
    ptt p2 = split(p1.second, r - l + 1);
    p2.first -> rev ^= 1;
    return join(join(p1.first, p2.first), p2.second);
}

int kth(treapNode *node, int k) {
    push(node);
    if(node -> l -> cnt + 1 == k)
        return node -> key;
    if(k > node -> l -> cnt) {
        return kth(node -> r, k - node -> l -> cnt - 1);
    }
    return kth(node -> l, k);
}

void inorder(treapNode *node) {
    if(node == emptyNode)
        return;

    push(node);
    inorder(node -> l);
    cout << node -> key << " ";
    inorder(node -> r);
}

void solve() {
    char ch; cin >> ch;

    if(ch == 'I') {
        int k, e; cin >> k >> e;
        root = ins(root, k, new treapNode{e, (int)(rng() % MOD), 1, 0, emptyNode, emptyNode});
        return;
    }

    if(ch == 'R') {
        int i, j; cin >> i >> j;
        root = rev(root, i, j);
        return;
    }

    if(ch == 'D') {
        int i, j; cin >> i >> j;
        root = rem(root, i, j);
        return;
    }

    int k; cin >> k; cout << kth(root, k) << "\n";
}

int main() {

    Open("secv8");

    int T, dump; cin >> T >> dump;
    for(;T;T--) {
        solve();
    }

    inorder(root);

    return 0;
}