Cod sursa(job #1789342)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 26 octombrie 2016 21:30:33
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.63 kb
#include <fstream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

ifstream fin("zeap.in");
ofstream fout("zeap.out");

constexpr int inf = 0x3f3f3f3f;

struct Tr {
    int key, pr, min, max, diffMin;
    Tr *lef, *rig;
    Tr(int key, int pr, int min, int max, int diffMin, Tr* lef, Tr* rig) :
        key(key), pr(pr), min(min), max(max), diffMin(diffMin), lef(lef), rig(rig) {}
} *root, *nil;

int nodeCount;

void Init( ) {

    srand(time(0));
    root = nil = new Tr(0, -1, inf, -inf, inf, nullptr, nullptr);

}

void Update(Tr* node) {

    if (node == nil)
        return;

    node->min = min(node->key, min(node->lef->min, node->rig->min));
    node->max = max(node->key, max(node->lef->max, node->rig->max));
    node->diffMin = min(node->lef->diffMin, node->rig->diffMin);

    if (node->lef != nil)
        node->diffMin = min(node->diffMin, node->key - node->lef->max);
    if (node->rig != nil)
        node->diffMin = min(node->diffMin, node->rig->min - node->key);

}

pair<Tr*, Tr*> Split(Tr* node, int key) {

    if (node == nil)
        return {nil, nil};

    pair<Tr*, Tr*> ret;
    if (key < node->key) {
        ret = Split(node->lef, key);
        node->lef = ret.second;
        ret.second = node;
    }
    else {
        ret = Split(node->rig, key);
        node->rig = ret.first;
        ret.first = node;
    }

    Update(node);
    return ret;

}

Tr* Join(Tr* l, Tr* r) {

    if (l == nil)
        return r;
    if (r == nil)
        return l;

    if (l->pr > r->pr) {
        l->rig = Join(l->rig, r);
        Update(l);
        return l;
    }
    else {
        r->lef = Join(l, r->lef);
        Update(r);
        return r;
    }

}

Tr* Insert(Tr* node, int key, int pr) {

    if (pr > node->pr) {
        auto aux = Split(node, key);
        node = new Tr(key, pr, key, key, inf, aux.first, aux.second);
    }
    else if (key < node->key)
        node->lef = Insert(node->lef, key, pr);
    else
        node->rig = Insert(node->rig, key, pr);

    Update(node);
    return node;

}

bool Find(Tr* node, int key) {

    if (node == nil)
        return false;
    if (node->key == key)
        return true;

    if (key < node->key)
        return Find(node->lef, key);
    else
        return Find(node->rig, key);

}

Tr* Erase(Tr* node, int key) {

    if (node == nil)
        return nil;
    if (node->key == key) {
        Tr* aux = node;
        node = Join(node->lef, node->rig);
        delete aux;
    }
    else if (key < node->key)
        node->lef = Erase(node->lef, key);
    else
        node->rig = Erase(node->rig, key);

    Update(node);
    return node;

}

int main( ) {

    Init();

    char buffer[20];
    while (fin >> buffer) {

        if (buffer[0] == 'I') {
            int x; fin >> x;
            if (!Find(root, x)) {
                nodeCount++;
                root = Insert(root, x, rand());
            }
        }
        else if (buffer[0] == 'S') {
            int x; fin >> x;
            if (!Find(root, x))
                fout << "-1\n";
            else {
                nodeCount--;
                root = Erase(root, x);
            }
        }
        else if (buffer[0] == 'C') {
            int x; fin >> x;
            fout << Find(root, x) << '\n';
        }
        else if (buffer[1] == 'A') {
            if (nodeCount < 2)
                fout << "-1\n";
            else
                fout << root->max - root->min << '\n';
        }
        else {
            if (nodeCount < 2)
                fout << "-1\n";
            else
                fout << root->diffMin << '\n';
        }

    }

    return 0;

}

//Trust me, I'm the Doctor!