Cod sursa(job #2887026)

Utilizator AlexandruabcdeDobleaga Alexandru Alexandruabcde Data 8 aprilie 2022 18:14:44
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.34 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f ("zeap.in");
ofstream g ("zeap.out");

constexpr int INF = 1e9 + 7;

mt19937 rng(213213);

struct Node {
    Node *L, *R;
    int val, prior;
    int sz;
    int Max, Min;
    int MinDif;
    Node() {}
    Node(int key) : L(nullptr), R(nullptr), val(key), prior(rng()), sz(1), Max(key), Min(key), MinDif(INF) { }
};

Node* Treap;

int Size (Node *T) {
    if (T == nullptr) return 0;

    return T->sz;
}

int Maximum (Node *T) {
    if (T == nullptr) return 0;

    return T->Max;
}

int Minimum (Node *T) {
    if (T == nullptr) return INF;

    return T->Min;
}

int MinimumDifference (Node *T) {
    if (T == nullptr) return INF;

    return T->MinDif;
}

void Update(Node* T) {
    T->sz = 1 + Size(T->L) + Size(T->R);
    T->Max = max(T->val, max(Maximum(T->L), Maximum(T->R)));
    T->Min = min(T->val, min(Minimum(T->L), Minimum(T->R)));
    T->MinDif = min(MinimumDifference(T->L), MinimumDifference(T->R));
    if (Size(T->L) > 0) T->MinDif = min(T->MinDif, T->val - Maximum(T->L));
    if (Size(T->R) > 0) T->MinDif = min(T->MinDif, Minimum(T->R) - T->val);
}

void Split (Node* Tree, int key, Node* &L, Node* &R) {
    if (Tree == nullptr) {
        L = nullptr;
        R = nullptr;
        return;
    }
    else if (Tree->val <= key) {
        Split(Tree->R, key, Tree->R, R);
        L = Tree;
    }
    else {
        Split(Tree->L, key, L, Tree->L);
        R = Tree;
    }

    Update(Tree);
}

void Merge (Node* &Tree, Node *A, Node *B) {
    if (A == nullptr) {
        Tree = B;
    }
    else if (B == nullptr) {
        Tree = A;
    }
    else {
        if (A->prior > B->prior) {
            Merge(A->R, A->R, B);
            Tree = A;
        }
        else {
            Merge(B->L, A, B->L);
            Tree = B;
        }
    }

    Update(Tree);
}

bool Cauta (Node* T, int value) {
    if (T == nullptr) return 0;

    if (T->val == value) return 1;

    if (T->val < value) return Cauta(T->R, value);

    return Cauta(T->L, value);
}

void Insert (int value) {
    bool is = Cauta(Treap, value);

    if (is) return;

    Node* Small;
    Node* Big;
    Node* new_value = new Node(value);

    Split(Treap, value, Small, Big);
    Merge(Small, Small, new_value);
    Merge(Treap, Small, Big);
}

void Delete (int value) {
    bool is = Cauta(Treap, value);

    if (!is) {
        g << -1 << '\n';
        return;
    }

    Node* Small;
    Node* Big;
    Node* Him;
    Split(Treap, value-1, Small, Big);
    Split(Big, value, Him, Big);
    Merge(Treap, Small, Big);
}

int main () {
    string Op;

    while (f >> Op) {
        int x;
        if (Op == "I") {
            f >> x;
            Insert(x);
        }
        else if (Op == "S") {
            f >> x;
            Delete(x);
        }
        else if (Op == "C") {
            f >> x;
            g << Cauta(Treap, x) << '\n';
        }
        else {
            if (Op == "MAX") {
                if (Size(Treap) < 2) g << -1 << '\n';
                else g << Maximum(Treap) - Minimum(Treap) << '\n';
            }
            else {
                if (Size(Treap) < 2) g << -1 << '\n';
                else g << MinimumDifference(Treap) << '\n';
            }
        }
    }

    return 0;
}