Cod sursa(job #3350574)

Utilizator unomMirel Costel unom Data 9 aprilie 2026 19:29:41
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.69 kb
#include <bits/stdc++.h>

using namespace std;

ifstream in("zeap.in");
ofstream out("zeap.out");
int INF = (1 << 30);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
struct Node
{
    int xmin;
    int xmax;
    int difmin;
    int difmax;

    int key;
    int prio;
    Node *left;
    Node *right;

    Node(int x)
    {
        xmin = x;
        xmax = x;
        difmin = INF;
        difmax = -1;

        key = x;
        prio = rng();
        left = nullptr;
        right = nullptr;
    }

    void recalc()
    {
        difmin = INF;
        xmin = key;
        if(left != nullptr)
        {
            xmin = left->xmin;

            difmin = min(difmin, left->difmin);
            difmin = min(difmin, key - left->xmax);
        }

        xmax = key;
        if(right != nullptr)
        {
            xmax = right->xmax;

            difmin = min(difmin, right->difmin);
            difmin = min(difmin, right->xmin - key);
        }

        difmax = -1;
        if(xmin != xmax)
        {
            difmax = xmax - xmin;
        }
    }
};

pair<Node*, Node*> split(Node *treap, int x)
{
    if(treap == nullptr)
    {
        return {nullptr, nullptr};
    }

    if(treap->key <= x)
    {
        auto [left, right] = split(treap->right, x);
        treap->right = left;
        treap->recalc();

        return {treap, right};
    }
    else
    {
        auto [left, right] = split(treap->left, x);
        treap->left = right;
        treap->recalc();

        return {left, treap};
    }
}

Node *merge(Node *left, Node *right)
{
    if(left == nullptr) return right;
    if(right == nullptr) return left;

    if(left->prio > right->prio)
    {
        left->right = merge(left->right, right);
        left->recalc();

        return left;
    }
    else
    {
        right->left = merge(left, right->left);
        right->recalc();

        return right;
    }
}

Node *add(Node *treap, int x)
{
    auto [left, full_right] = split(treap, x - 1);
    auto [sub, right] = split(full_right, x);

    if(sub != nullptr)
    {
        delete sub;
    }

    Node *newNode = new Node(x);
    return merge(left, merge(newNode, right));
}

Node *del(Node *treap, int x)
{
    auto [left, full_right] = split(treap, x - 1);
    auto [sub, right] = split(full_right, x);

    if(sub != nullptr)
    {
        delete sub;
    }
    else
    {
        out<<-1<<'\n';
    }

    return merge(left, right);
}

int find_num(Node *treap, int x)
{
    if(treap == nullptr) return 0;

    if(treap->key == x)
    {
        return 1;
    }
    else if(treap->key < x)
    {
        return find_num(treap->right, x);
    }
    else
    {
        return find_num(treap->left, x);
    }
}

int query_max(Node *treap)
{
    if(treap == nullptr) return -1;
    if(treap->difmax == -1) return -1;
    return treap->difmax;
}

int query_min(Node *treap)
{
    if(treap == nullptr) return -1;
    if(treap->difmin == INF) return -1;
    return treap->difmin;
}

int main()
{
    Node *treap = nullptr;

    string tip;
    int x;
    while(in>>tip)
    {
        if(tip == "I")
        {
            in>>x;
            treap = add(treap, x);
        }
        else if(tip == "S")
        {
            in>>x;
            treap = del(treap, x);
        }
        else if(tip == "C")
        {
            in>>x;
            out<<find_num(treap, x)<<'\n';
        }
        else if(tip == "MAX")
        {
            out<<query_max(treap)<<'\n';
        }
        else
        {
            out<<query_min(treap)<<'\n';
        }
    }

    return 0;
}