Cod sursa(job #1827204)

Utilizator mariakKapros Maria mariak Data 11 decembrie 2016 15:59:45
Problema Zeap Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.24 kb
#include <bits/stdc++.h>
#define inf 2000000000
FILE *fin  = freopen("zeap.in", "r", stdin);
FILE *fout = freopen("zeap.out", "w", stdout);

using namespace std;
char s[20];
struct Node
{
    int val, maxx, minn, MAX, MIN;
    long long priority;
    Node *left;
    Node *right;
};
Node *emptyNode = new Node();

void recompute(Node* root)
{
    root->minn = min(root->left->minn, root->val);
    root->maxx = max(root->right->maxx, root->val);
    if(root->left == emptyNode && root->right == emptyNode)
        root->MAX = root->MIN = -1;
    else if(root->left == emptyNode)
    {
        if(root->right->MIN == - 1)
            root->MAX = root->MIN = abs(root->val - root->right->val);
        else
        {
            if(root->left->minn - root->val < root->right->MIN)
                root->MIN = root->right->minn - root->val;
            else root->MIN = root->right->MIN;

            if(root->maxx - root->minn > root->right->MAX)
                root->MAX = root->maxx - root->minn;
            else root->MAX = root->right->MAX;
        }
    }
    else if(root->right == emptyNode)
    {
        if(root->left->MIN == - 1)
            root->MAX = root->MIN = abs(root->val - root->left->val);
        else
        {
            if(root->val - root->left->maxx < root->left->MIN)
                root->MIN = root->val - root->left->maxx;
            else root->MIN = root->left->MIN;

            if(root->maxx - root->minn > root->left->MAX)
                root->MAX = root->maxx - root->minn;
            else root->MAX = root->left->MAX;
        }
    }
    else
    {
        root->MAX = max(root->left->MAX, root->right->MAX);
        root->MIN = min(root->left->MIN, root->right->MIN);
        if(root->val - root->left->maxx < root->MIN)
            root->MIN = root->val - root->left->maxx;
        if(root->right->minn - root->val < root->MIN)
            root->MIN = root->right->minn - root->val;
        if(root->maxx - root->minn > root->MAX)
            root->MAX = root->maxx - root->minn;
    }
}

pair<Node*, Node*> split(Node* root, int value)
{
    pair<Node*, Node*> p;
    if (root == emptyNode)
    {
        p.first = emptyNode;
        p.second = emptyNode;
    }
    else if (value < root->val)
    {
        pair<Node*, Node*> q = split(root->left, value);
        p.first = q.first;
        root->left = q.second;
        p.second = root;
        recompute(root);
    }
    else // if (root->val <= value)
    {
        pair<Node*, Node*> q = split(root->right, value);
        p.second = q.second;
        root->right = q.first;
        p.first = root;
        recompute(root);
    }
    return p;
}

Node* join(Node* first, Node* second)
{
    if(first == emptyNode)
        return second;
    if(second == emptyNode)
        return first;
    else if(first->priority  < second->priority)
    {
        second->left = join(first, second->left);
        recompute(second);
        return second;
    }
    else //if(second->priority < first->priority)
    {
        first->right = join(first->right, second);
        recompute(first);
        return first;
    }
}

Node* insert(Node* root, int value)
{
    Node* newNode = new Node;
    newNode->val = newNode->minn = newNode->maxx = value;
    newNode->MIN = -1;
    newNode->MAX = -1;
    newNode->left = newNode->right = emptyNode;
    newNode->priority =((long long)rand() << 45
                        ^ (long long)rand() << 30
                        ^ (long long)rand() << 15
                        ^ (long long)rand() <<  0)
                       & 0x7fffffffffffffff;
    pair <Node*, Node*> p = split(root, value);
    return join(join(p.first, newNode), p.second);
}

Node* erase(Node* root, int value)
{
    pair<Node*, Node*> p = split(root, value);
    pair<Node*, Node*> q = split(p.first, value - 1);
    return join(q.first, p.second);
}

bool search(Node* root, int value)
{
    if(root == emptyNode)
        return 0;
    if(root->val == value)
        return 1;
    if(root->val < value)
        return search(root->right, value);
    else return search(root->left, value);
}

int createNumber()
{
    int ans = 0;
    int p = 1;
    for(int i = strlen(s) - 1; i > 1; -- i, p *= 10)
        ans += p * (s[i] - '0');
    return ans;
}

int main()
{
    emptyNode->val = 0;
    emptyNode->maxx = -inf;
    emptyNode->MAX = emptyNode->MIN = -1;
    emptyNode->minn = inf;
    emptyNode->priority = -1;
    emptyNode->left = emptyNode->right = emptyNode;
    Node* root = emptyNode;

    while(gets(s))
    {
        if(s[0] == 'I')
        {
            int x = createNumber();
            root = insert(root, x);
        }
        else if(s[0] == 'S')
        {
            int x = createNumber();
            if(search(root, x) == 0)
                printf("-1\n");
            else root = erase(root, x);
        }
        else if(s[0] == 'C')
        {
            int x = createNumber();
            if(search(root, x) == 0)
                printf("0\n");
            else printf("1\n");
        }
        else if(s[0] == 'M' && s[1] == 'A')
            printf("%d\n", root->MAX);
        else
            printf("%d\n", root->MIN);
    }
    return 0;
}