Cod sursa(job #1788394)

Utilizator cristina_borzaCristina Borza cristina_borza Data 25 octombrie 2016 22:48:05
Problema Zeap Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.9 kb
#include <fstream>
#include <cstring>
#include <cstdlib>
#include <ctime>

#define INF 100000000

using namespace std;

ifstream f ("zeap.in");
ofstream g ("zeap.out");

char sir[10];
int x;

struct TreapNode {
    TreapNode *left , *right;
    int df , key , priority , maxx , minn;
};

TreapNode *rotate_right (TreapNode *y) {
    TreapNode *x = y -> left , *T2 = x -> right;

    x -> right = y;
    y -> left = T2;

    return x;
}

TreapNode *rotate_left (TreapNode *x) {
    TreapNode *y = x -> right , *T2 = y -> left;

    y -> left = x;
    x -> right = T2;

    return y;
}

TreapNode *newNode(int key) {
    TreapNode* temp = new TreapNode;

    temp -> key = key;
    temp -> priority = rand() % 100000;
    temp -> df = INF;
    temp -> maxx = key;
    temp -> minn = key;
    temp -> left = temp -> right = NULL;

    return temp;
}


TreapNode* search (TreapNode *node , int v) {
    if (node == NULL || node -> key == v) {
        return node;
    }

    if (v > node -> key) {
        return search (node -> right , v);
    }

    if (v < node -> key) {
        return search (node -> left , v);
    }
}

TreapNode* insert (TreapNode *node , int v) {
    if (node == NULL) {
        return newNode (v);
    }

    if (v <= node -> key) {
        node -> left = insert (node -> left , v);

        if (node -> left -> priority > node -> priority) {
            node = rotate_right (node);
        }
    }

    if (v > node -> key) {
        node -> right = insert (node -> right , v);

        if (node -> right -> priority > node -> priority) {
            node = rotate_left (node);
        }
    }


    int dmin = INF , amx = 0 , amn = INF;
    if (node -> left != NULL) {
        dmin = min (dmin , node -> left -> df);
        dmin = min (dmin , node -> key - node -> left -> maxx);

        amn = min (amn , node -> left -> minn);
        amx = max (amx , node -> left -> maxx);
    }

    if (node -> right != NULL) {
        dmin = min (dmin , node -> right -> df);
        dmin = min (dmin , node -> right -> minn - node -> key);


        amn = min (amn , node -> right -> minn);
        amx = max (amx , node -> right -> maxx);
    }

    node -> df = dmin;
    return node;
}


TreapNode *dlt (TreapNode *node , int v) {
    //nu exista nodul nodul pe car e vreau sa il sterg
    if (node == NULL) {
        return node;
    }

    // nodul pe care vreau sa il sterg nu este node
    else if (v < node -> key) {
        node -> left = dlt (node -> left , v);
    }

    else if (v > node -> key) {
        node -> right = dlt (node -> right , v);
    }

    // nodul pe care vreau sa il sterg este node

    else if (node -> left == NULL) {
        TreapNode *aux = node -> right;
        delete (node);
        node = aux;
    }

    else if (node -> right == NULL) {
        TreapNode *aux = node -> left;
        delete (node);
        node = aux;
    }

    //exisata ambii fii

    else if (node -> right != NULL && node -> left != NULL) {
        if (node -> right -> priority > node -> left -> priority) {
            node = rotate_left (node);
            node -> left = dlt (node -> left , v);
        }

        else {
            node = rotate_right (node);
            node -> right = dlt (node -> right , v);
        }
    }

    //calculez diferenta minima;
   int dmin = INF , amx = 0 , amn = INF;
    if (node -> left != NULL) {
        dmin = min (dmin , node -> left -> df);
        dmin = min (dmin , node -> key - node -> left -> maxx);

        amn = min (amn , node -> left -> minn);
        amx = max (amx , node -> left -> maxx);
    }

    if (node -> right != NULL) {
        dmin = min (dmin , node -> right -> df);
        dmin = min (dmin , node -> right -> minn - node -> key);

        amn = min (amn , node -> right -> minn);
        amx = max (amx , node -> right -> maxx);
    }

    node -> df = dmin;
    return node;
}

TreapNode *findmin (TreapNode *node) {
    if (node == NULL) {
        return node;
    }
    if (node -> left != NULL) {
        return findmin(node -> left);
    }

    else {
        return node;
    }
}

TreapNode *findmax (TreapNode *node) {
    if (node == NULL) {
        return node;
    }
    if (node -> right != NULL) {
        return findmax (node -> right);
    }

    else {
        return node;
    }
}

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

    TreapNode *root = NULL;
    while (f >> sir) {
        if (strcmp (sir , "MAX") == 0) {
            TreapNode *mn = findmin (root);
            TreapNode *mx = findmax (root);

            if (mn != NULL && mx != NULL) {
                int ans = mx -> key - mn -> key;
                if (ans == 0)
                    ans = -1;
                g << ans << '\n';
            }

            else {
                g << -1 << '\n';
            }
        }

        if (strcmp (sir , "MIN") == 0) {
            TreapNode *aux = root;
            if (root == NULL) {
                g << -1 << '\n';
                continue;
            }
            if (aux -> df == INF)
                g << -1 << '\n';
            else
                g << aux -> df << '\n';
        }

        if (strcmp (sir , "I") == 0) {
            f >> x;
            root = insert (root , x);
        }

        if (strcmp (sir , "C") == 0) {
            f >> x;
            TreapNode *aux = search (root , x);
            if (aux == NULL) {
                g << 0 << '\n';
            }

            else {
                g << 1 << '\n';
            }
        }

        if (strcmp (sir , "S") == 0) {
            f >> x;
            TreapNode *aux = search (root , x);
            if (aux == NULL) {
                g << -1 << '\n';
            }

            else {
                root = dlt (root , x);
            }
        }
    }
    return 0;
}