Cod sursa(job #3148993)

Utilizator radustn92Radu Stancu radustn92 Data 5 septembrie 2023 17:28:11
Problema Secv8 Scor 25
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.96 kb
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <vector>
using namespace std;

struct node {
    int value;
    
    int priority;
    
    int cnt;

    bool rev;

    node* left;

    node* right;

    node(int _value) : value(_value) {
        priority = rand();
        cnt = 1;
        rev = false;
        left = right = nullptr;
    }
};
typedef node* pnode;
pnode root;

int getSize(pnode root) {
    return root == nullptr ? 0 : root -> cnt;
}

void updateSize(pnode root) {
    if (root != nullptr) {
        root -> cnt = 1 + getSize(root -> left) + getSize(root -> right);
    }
}

void pushUpdates(pnode root) {
    if (root != nullptr && root -> rev) {
        swap(root -> left, root -> right);
        root -> rev = false;
        if (root -> left != nullptr) {
            root -> left -> rev ^= true;
        }
        if (root -> right != nullptr) {
            root -> right -> rev ^= true;
        }
    }
}

pair<pnode, pnode> split(pnode root, int key, int add = 0) {
    if (root == nullptr) {
        return {nullptr, nullptr};
    }
    pushUpdates(root);
    int currKey = add + getSize(root -> left);
    pair<pnode, pnode> result;
    if (currKey <= key) {
        auto rightSplit = split(root -> right, key, currKey + 1);
        root -> right = rightSplit.first;
        result = {root, rightSplit.second};
    } else {
        auto leftSplit = split(root -> left, key, add);
        root -> left = leftSplit.second;
        result = {leftSplit.first, root};
    }
    updateSize(root);
    return result;
}

pnode merge(pnode root1, pnode root2) {
    if (root1 == nullptr || root2 == nullptr) {
        return root1 == nullptr ? root2 : root1;
    }
    pushUpdates(root1);
    pushUpdates(root2);
    pnode result;
    if (root1 -> priority > root2 -> priority) {
        root1 -> right = merge(root1 -> right, root2);
        result = root1;
    } else {
        root2 -> left = merge(root1, root2 -> left);
        result = root2;
    }
    updateSize(result);
    return result;
}

void debug(pnode root, vector<int>& result) {
    if (root == nullptr) {
        return;
    }
    debug(root -> left, result);
    result.push_back(root -> value);
    debug(root -> right, result);
}

vector<int> debug() {
    vector<int> result;
    result.reserve(getSize(root));
    debug(root, result);
    return result;
}

void insert(pnode& root, int pos, int value) {
    pnode newNode = new node(value);
    auto lt = split(root, pos - 1);
    root = merge(lt.first, newNode);
    root = merge(root, lt.second);
}

int get(pnode& root, int k) {
    auto lt = split(root, k - 1);
    auto ge = split(lt.second, 0);
    int result = ge.first -> value;
    root = merge(ge.first, ge.second);
    root = merge(lt.first, root);
    return result;
}

void reverse(pnode& root, int from, int to) {
    auto lt = split(root, from - 1);
    auto ge = split(lt.second, to - from);
    ge.first -> rev ^= true;
    root = merge(ge.first, ge.second);
    root = merge(lt.first, root);
}

void erase(pnode& root, int from, int to) {
    auto lt = split(root, from - 1);
    auto ge = split(lt.second, to - from);
    root = merge(lt.first, ge.second);
}

int main() {
    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);

    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int N, revExists;
    string op;
    int a, b;
    cin >> N >> revExists;
    for (int idx = 0; idx < N; idx++) {
        cin >> op;
        if (op == "I") {
            cin >> a >> b;
            insert(root, a - 1, b);
        } else if (op == "A") {
            cin >> a;
            // cout << "ACCESS " << a - 1 << "\n";
            cout << get(root, a - 1) << "\n";
        } else if (op == "R") {
            cin >> a >> b;
            reverse(root, a - 1, b - 1);
        } else if (op == "D") {
            cin >> a >> b;
            erase(root, a - 1, b - 1);
        }
    }
    for (auto entry : debug()) {
        cout << entry << " ";
    }
    cout << "\n";
    return 0;
}