Cod sursa(job #1806586)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 15 noiembrie 2016 15:42:13
Problema Zeap Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.21 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#define LOCAL
using namespace std;
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define INF 2000000000

typedef struct _treap
{
    int key, pri, vmin, vmax, dmin;
    _treap *l, *r;

    _treap(int _key) : key(_key), pri(rand()), l(nullptr), r(nullptr), vmin(_key), vmax(_key), dmin(INF) {}
} *treap;

void update(treap root)
{
    if (!root) return;

    root->vmin = root->vmax = root->key;
    root->dmin = INF;
    if (root->l)
    {
        root->vmin = root->l->vmin;
        root->dmin = min(root->dmin, root->l->dmin);
        root->dmin = min(root->dmin, root->key - root->l->vmax);
    }
    if (root->r)
    {
        root->vmax = root->r->vmax;
        root->dmin = min(root->dmin, root->r->dmin);
        root->dmin = min(root->dmin, root->r->vmin - root->key);
    }
}

void split(treap root, int key, treap &l, treap &r)
{
    if (!root) { l = r = nullptr; return; }

    if (root->key < key) split(root->r, key, root->r, r), l = root;
    else split(root->l, key, l, root->l), r = root;

    update(root);
}

void merge(treap &root, treap l, treap r)
{
    if (!l || !r) { root = l ? l : r; return; }

    if (l->pri < r->pri) merge(r->l, l, r->l), root = r;
    else merge(l->r, l->r, r), root = l;

    update(root);
}

void insert(treap &root, treap item)
{
    if (!root) { root = item; return; }

    if (root->pri < item->pri) split(root, item->key, item->l, item->r), root = item;
    else insert(root->key < item->key ? root->r : root->l, item);

    update(root);
}

bool erase(treap &root, int key)
{
    if (!root) return false;

    bool ret;
    if (root->key == key) merge(root, root->l, root->r), ret = true;
    else ret = erase(root->key < key ? root->r : root->l, key);

    update(root);
    return ret;
}

bool find(treap root, int key)
{
    if (!root) return false;
    if (root->key == key) return true;
    return find(root->key < key ? root->r : root->l, key);

    update(root);
}

int main()
{
#ifdef  LOCAL
	freopen("zeap.in", "r", stdin);
	freopen("zeap.out", "w", stdout);
#endif

	int x;
    char op[5];
    treap root = nullptr;

    while (scanf("%s", op) != EOF)
    {
        switch (op[0])
        {
            case 'I':
                scanf("%d", &x);
                insert(root, new _treap(x));
                break;

            case 'S':
                scanf("%d", &x);
                if (!erase(root, x)) printf("%d\n", -1);
                break;

            case 'C':
                scanf("%d", &x);
                printf("%d\n", find(root, x));
                break;

            case 'M':
                if (op[1] == 'I')
                {
                    printf("%d\n", root && root->dmin != INF ? root->dmin : -1);
                }
                else
                {
                    printf("%d\n", root && root->dmin != INF ? root->vmax - root->vmin : -1);
                }
                break;
            default:
                break;
        }
    }



    return 0;
}