Cod sursa(job #1837223)

Utilizator antanaAntonia Boca antana Data 29 decembrie 2016 12:00:31
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.03 kb
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <ctime>
#include <algorithm>

#define INF 0x3f3f3f3f
#define MAXN 300

using namespace std;

struct Treap{
    int difmin, sz, key, priority, mini, maxi;
    Treap *left, *right;

    Treap(int key, int priority){
        this->key = key;
        this->priority = priority;
        this->sz = 1;
        this->difmin = INF;
        this->mini = this->maxi = key;
    }
}*root;

int found;
char s[MAXN], *p;

void refresh(Treap *node)
{
    node->mini = node->maxi = node->key;
    node->difmin = INF;
    node->sz = 1;

    if(node->left != NULL)
    {
        node->sz += node->left->sz;
        node->mini = min(node->mini, node->left->mini);
        node->maxi = max(node->maxi, node->left->maxi);
        node->difmin = min(node->difmin, node->key - node->left->maxi);
        node->difmin = min(node->difmin, node->left->difmin);
    }
    if(node->right != NULL)
    {
        node->sz += node->right->sz;
        node->mini = min(node->mini, node->right->mini);
        node->maxi = max(node->maxi, node->right->maxi);
        node->difmin = min(node->difmin, node->right->mini - node->key);
        node->difmin = min(node->difmin, node->right->difmin);
    }
}

Treap* leftToRight(Treap *node)
{
    Treap *aux = node->left;

    node->left = aux->right;
    aux->right = node;

    refresh(node);
    refresh(aux);

    return aux;
}

Treap* rightToLeft(Treap *node)
{
    Treap *aux = node->right;

    node->right = aux->left;
    aux->left = node;

    refresh(node);
    refresh(aux);

    return aux;
}

Treap* balance(Treap *node)
{
    if(node->left != NULL && node->left->priority > node->priority)
        return leftToRight(node);
    if(node->right != NULL && node->right->priority > node->priority)
        return rightToLeft(node);

    refresh(node);
    return node;
}

Treap* insertInTreap(Treap *node, int key, int priority)
{
    if(node == NULL)
        return node = new Treap(key, priority);

    if(node->key == key)
    {
        found = 1;
        return node;
    }

    if(key < node->key)
        node->left = insertInTreap(node->left, key, priority);
    else node->right = insertInTreap(node->right, key, priority);

    return balance(node);
}

Treap* deleteFromTreap(Treap *node, int key)
{
    if(node == NULL)
        return NULL;

    Treap *aux;

    if(key == node->key)
    {
        if(node->left == NULL)
        {
            if(node->right == NULL)
            {
                found = 0;
                delete node;
                return NULL;
            }
            else
            {
                aux = rightToLeft(node);
                aux->left = deleteFromTreap(aux->left, key);
            }
        }
        else
        {
            if(node->right == NULL || node->right->priority < node->left->priority)
            {
                aux = leftToRight(node);
                aux->right = deleteFromTreap(aux->right, key);
            }
            else
            {
                aux = rightToLeft(node);
                aux->left = deleteFromTreap(aux->left, key);
            }
        }

        return balance(aux);
    }

    if(key < node->key)
        node->left = deleteFromTreap(node->left, key);
    else node->right = deleteFromTreap(node->right, key);

    return balance(node);
}

void searchInTreap(Treap *node, int key)
{
    if(node == NULL)
        return;

    if(node->key == key)
    {
        found = 1;
        return;
    }

    if(key < node->key)
        searchInTreap(node->left, key);
    else searchInTreap(node->right, key);
}

int getNumber()
{
    int nr = 0;

    while(!isdigit(*p)) ++p;
    while(isdigit(*p))
    {
        nr = nr*10 + *p-'0';
        ++p;
    }

    return nr;
}

inline int maxDifference()
{
    if(root == NULL || root->sz < 2) return -1;

    return root->maxi - root->mini;
}

inline int minDifference()
{
    if(root == NULL || root->sz < 2) return -1;

    return root->difmin;
}

int main()
{
    srand(time(0));

    freopen("zeap.in", "r", stdin);
    freopen("zeap.out", "w", stdout);

    int nr;

    gets(s);
    p = s;

    while(s[0]>='A' && s[0]<='Z')
    {
        p = s;
        if(*p == 'I')
        {
            nr = getNumber();
            root = insertInTreap(root, nr, rand());

            s[0] = NULL;
            gets(s);
            continue;
        }
        if(*p == 'S')
        {
            found = -1;
            nr = getNumber();

            root = deleteFromTreap(root, nr);
            if(found != 0) printf("-1\n");

            s[0] = NULL;
            gets(s);
            continue;
        }
        if(*p == 'C')
        {
            found = 0;
            nr = getNumber();

            searchInTreap(root, nr);
            printf("%d\n", found);

            s[0] = NULL;
            gets(s);
            continue;
        }

        if(*(p+1) == 'A')
        {
            printf("%d\n", maxDifference());

            s[0] = NULL;
            gets(s);
            continue;
        }

        printf("%d\n", minDifference());

        s[0] = NULL;
        gets(s);
        continue;
    }

    return 0;
}