Cod sursa(job #3264343)

Utilizator not_anduAndu Scheusan not_andu Data 20 decembrie 2024 16:16:01
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.65 kb
#include <bits/stdc++.h>

using namespace std;

#define INFILE "secv8.in"
#define OUTFILE "secv8.out"

const int N_MAX = 2e9;
const int AUX_NODE = 69;

struct TreapNode {
public:
    int value;
    int priority;
    int size;

    bool rev;
    TreapNode *left, *right;

    TreapNode(int _value, int _priority, int _size, TreapNode *_left, TreapNode *_right) : 
        value(_value), priority(_priority), size(_size), rev(false), left(_left), right(_right) {}

};

TreapNode *treap;
TreapNode *nil = new TreapNode(0, -1, 0, nullptr, nullptr);

inline void getSize(TreapNode *node) {
    node -> size = node -> left -> size + node -> right -> size + 1;
}

inline void updateRev(TreapNode *node) {
    if(node -> rev){
        swap(node -> left, node -> right);
        node -> rev = false;
        node -> left -> rev ^= 1;
        node -> right -> rev ^= 1;
    }
}

void rotateLeft(TreapNode *&node){
    TreapNode *aux = node -> right;
    node -> right = aux -> left;
    aux -> left = node;
    getSize(node);
    node = aux;
    getSize(node);
}

void rotateRight(TreapNode *&node){
    TreapNode *aux = node -> left;
    node -> left = aux -> right;
    aux -> right = node;
    getSize(node);
    node = aux;
    getSize(node);
}

void insert(TreapNode *&node, int position, int value, int priority) {
    if(node == nil) {
        node = new TreapNode(value, priority, 1, nil, nil);
        return;
    }

    updateRev(node);

    if(position <= node -> left -> size + 1) insert(node -> left, position, value, priority);
    else insert(node -> right, position - node -> left -> size - 1, value, priority);

    if(node -> left -> priority > node -> priority) rotateRight(node);
    else if(node -> right -> priority > node -> priority) rotateLeft(node);

    getSize(node);

}

int getValue(TreapNode *node, int position){

    updateRev(node);

    if(position == node -> left -> size + 1) return node -> value;
    if(position <= node -> left -> size) return getValue(node -> left, position);
    else return getValue(node -> right, position - node -> left -> size - 1);

}

void erase(TreapNode *&node, int position){

    updateRev(node);

    if(position != node -> left -> size + 1) {
        if(position <= node -> left -> size) erase(node -> left, position);
        else erase(node -> right, position - node -> left -> size - 1);
        getSize(node);
        return;
    }

    if(node -> left == nil && node -> right == nil) {
        delete node;
        node = nil;
        return;
    }

    if(node -> left -> priority > node -> right -> priority) {
        updateRev(node -> left);
        rotateRight(node);
        erase(node -> right, node -> right -> left -> size + 1);
    }
    else {
        updateRev(node -> right);
        rotateLeft(node);
        erase(node -> left, node -> left -> left -> size + 1);
    }

    getSize(node);

}

void eraseTree(TreapNode *&node) {
    if(node -> left != nil) eraseTree(node -> left);
    if(node -> right != nil) eraseTree(node -> right);

    delete node;
    node = nil;
}

TreapNode *split(TreapNode *&node, int position){
    insert(node, position, AUX_NODE, N_MAX);
    TreapNode *left = node -> left;
    TreapNode *right = node -> right;
    delete node;
    node = left;
    return right;
} 

void join(TreapNode *&node, TreapNode *other) {
    node = new TreapNode(AUX_NODE, N_MAX, node -> size + other -> size + 1, node, other);
    erase(node, node -> left -> size + 1);
}

void print(TreapNode *node) {
    
    if(node == nil) return;

    updateRev(node);
    print(node -> left);
    cout << node -> value << " ";
    print(node -> right);

}

void solve(){

    int queries; 
    bool existsReverse;
    cin >> queries >> existsReverse;

    treap = nil;
    while(queries--){
        char type; cin >> type;
        int x, y;
        TreapNode *oper_range, *after;
        if(type == 'I'){
            cin >> x >> y;
            insert(treap, x, y, rand() % N_MAX);
        }
        else if(type == 'A'){
            cin >> x;
            cout << getValue(treap, x) << '\n';
        }
        else if(type == 'R'){
            cin >> x >> y;
            after = split(treap, y + 1);
            oper_range = split(treap, x);
            oper_range -> rev = true;
            join(treap, oper_range);
            join(treap, after);
        }
        else {
            cin >> x >> y;
            after = split(treap, y + 1);
            oper_range = split(treap, x);
            eraseTree(oper_range);
            join(treap, after);
        }
    }

    print(treap);
    cout << '\n';

}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    freopen(INFILE, "r", stdin);
    freopen(OUTFILE, "w", stdout);
    solve();
    return 0;
}