Cod sursa(job #1837072)

Utilizator antanaAntonia Boca antana Data 28 decembrie 2016 23:12:04
Problema Zeap Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.32 kb
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#include <cstring>

#define INF 0x3f3f3f3f
#define MAXN 100

using namespace std;

struct Treap{
    int key, priority, mindif;
    Treap *left, *right;

    Treap(int key, int priority){
        this->key = key;
        this->priority = priority;
        this->left = this->right = NULL;
        this->mindif = INF;
    }
}*root;

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

inline void refresh(Treap *node)
{
    node->mindif = INF;

    if(node->left != NULL && abs(node->key - node->left->key) < node->mindif)
        node->mindif = min(node->mindif, abs(node->key - node->left->key));

    if(node->right != NULL && abs(node->key - node->right->key) < node->mindif)
        node->mindif = min(node->mindif, abs(node->key - node->right->key));

    if(node->left != NULL)
        node->mindif = min(node->mindif, node->left->mindif);

    if(node->right != NULL)
        node->mindif = min(node->mindif, node->right->mindif);
}

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

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

    refresh(node);
    refresh(aux);

    return aux;
}

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

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

    refresh(node);
    refresh(aux);

    return aux;
}

inline 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;
}

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

    if(node->key == key)
        return node;

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

    return balance(node);
}

inline Treap* deleteFromTreap(Treap *node, int key)
{
    if(node == NULL)
    {
        found = -1;
        return NULL;
    }

    Treap *aux;

    if(key == node->key)
    {
        if(node->left == NULL)
        {
            if(node->right == NULL)
            {
                k--;
                delete node;
                return NULL;
            }
            else
            {
                aux = rightToLeft(node);
                aux->left = deleteFromTreap(aux->left, key);
            }
        }
        else
        {
            if(node->right == NULL || node->left->priority > node->right->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);
}

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

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

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

int leftest(Treap *node)
{
    if(node->left == NULL)
        return node->key;
    return leftest(node->left);
}

int rightest(Treap *node)
{
    if(node->right == NULL)
        return node->key;
    return rightest(node->right);
}

inline int maxDifference()
{
    if(k < 2) return -1;
    return rightest(root) - leftest(root);
}

inline int minDifference()
{
    if(k < 2) return -1;
    return root->mindif;
}


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

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

    int nr;
    gets(s);
    while(s[0]>='A' && s[0] <= 'Z')
    {
        nr = 0;
        p = s;

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

            root = insertInTreap(root, nr, rand());
            s[0] = NULL;
            gets(s);
            continue;
        }
        if(*p == 'S')
        {
            p++;
            while(!isdigit(*p)) p++;
            while(isdigit(*p))
            {
                nr = nr*10 + *p-'0';
                p++;
            }

            found = 0;
            root = deleteFromTreap(root, nr);
            if(found == -1)
                printf("-1\n");
            s[0] = NULL;
            gets(s);
            continue;
        }
        if(*p == 'C')
        {
            p++;
            while(!isdigit(*p)) p++;
            while(isdigit(*p))
            {
                nr = nr*10 + *p-'0';
                p++;
            }

            found = 0;
            findInTreap(root, nr);
            printf("%d\n", found);
            s[0] = NULL;
            gets(s);
            continue;
        }
        if(*p == 'M' && *(p+1) == 'A')
        {
            printf("%d\n", maxDifference());
            s[0] = NULL;
            gets(s);
            continue;
        }
        printf("%d\n", minDifference());
        s[0] = NULL;
        gets(s);
    }

    return 0;
}