Cod sursa(job #3156999)

Utilizator amcbnCiobanu Andrei Mihai amcbn Data 14 octombrie 2023 01:29:34
Problema Zeap Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.71 kb
#include <bits/stdc++.h>
#include <random>
#include <chrono>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const char nl = '\n';
const char sp = ' ';
const int inf = 0x3f3f3f3f;
const long long INF = 1000000000000000000;
const int mod = 1e9 + 7;
const char out[2][4]{ "NO", "YES" };
#define all(a) a.begin(), a.end()
using ll = long long;
ifstream fin("zeap.in");
ofstream fout("zeap.out");

#define variableName(var) #var
#define __debug(var) cout << #var << " = " << var << '\n'
inline int rint(int a, int b) { return uniform_int_distribution<int>(a, b)(rng); }

struct treap {
    treap* left, * right;
    int priority; // prioritatea
    int key; // valoarea
    int max_element;
    int min_element;
    int max_difference;
    int min_difference;
    int size;
    treap(int value) {
        left = right = nullptr;
        priority = rand();
        key = value;
        max_element = min_element = value;
        max_difference = -inf;
        min_difference = inf;
        size = 1;
    }
};

void print(treap* root) {
    if (root == nullptr) {
        return;
    }
    print(root->left);
    cout << root->key << sp;
    print(root->right);
}

void update(treap* root) {
    if (root == nullptr || root->left == nullptr) {
        return;
    }
    if (root->right != nullptr) {
        root->max_difference = root->right->max_element - root->left->min_element;
        root->min_difference = min({ root->left->min_difference, root->right->min_difference, root->right->min_element - root->key, root->key - root->left->max_element });
        root->max_element = root->right->max_element;
        root->min_element = root->left->min_element;
        root->size = root->left->size + root->right->size + 1;
    }
    else {
        root->max_difference = root->key - root->left->min_element;
        root->min_difference = min(root->left->min_difference, root->key - root->left->max_element);
        root->max_element = root->key;
        root->min_element = root->left->min_element;
        root->size = root->left->size + 1;
    }
}

void split(treap* root, int key, treap*& left, treap*& right) {
    if (root == nullptr) {
        left = right = nullptr;
    }
    else if (key < root->key) {
        split(root->left, key, left, root->left);
        right = root;
    }
    else {
        split(root->right, key, root->right, right);
        left = root;
    }
    update(root);
}

void merge(treap*& root, treap* left, treap* right) {
    if (left == nullptr || right == nullptr) {
        root = left ? left : right;
        return;
    }
    if (left->priority > right->priority) {
        merge(left->right, left->right, right);
        root = left;
    }
    else {
        merge(right->left, left, right->left);
        root = right;
    }
    update(root);
}

void insert(treap*& root, treap* element) {
    treap* left, * right;
    split(root, element->key, left, right);
    merge(left, left, element);
    merge(root, left, right);
}

void erase(treap*& root, int key) {
    treap* left, * right, * temp;
    split(root, key, root, right);
    split(root, key - 1, left, temp);
    merge(root, left, right);
}

bool search(treap* root, int key) {
    if (root == nullptr) {
        return false;
    }
    if (root->key == key) {
        return true;
    }
    if (key < root->key) {
        return search(root->left, key);
    }
    else {
        return search(root->right, key);
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    treap* zeap = nullptr;
    string ln;
    while (getline(fin, ln)) {
        stringstream ss(ln);
        string tok;
        int element;
        ss >> tok;
        if (tok == "I") {
            ss >> element;
            if (search(zeap, element)) {
                continue;
            }
            insert(zeap, new treap(element));
        }
        else if (tok == "S") {
            ss >> element;
            if (!search(zeap, element)) {
                fout << -1 << nl;
                continue;
            }
            erase(zeap, element);
        }
        else if (tok == "C") {
            ss >> element;
            fout << search(zeap, element) << nl;
        }
        else if (tok == "MAX") {
            if (zeap == nullptr || zeap->size < 2) {
                fout << -1 << nl;
                continue;
            }
            fout << zeap->max_difference << nl;
        }
        else if (tok == "MIN") {
            if (zeap == nullptr || zeap->size < 2) {
                fout << -1 << nl;
                continue;
            }
            fout << zeap->min_difference << nl;
        }
    }
}