Cod sursa(job #2642724)

Utilizator PatrickCplusplusPatrick Kristian Ondreovici PatrickCplusplus Data 16 august 2020 22:40:29
Problema Zeap Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.33 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("zeap.in");
ofstream fout("zeap.out");

const int inf = 1e9;

int q, nr;
string op;

struct treap{
    int key, priority;
    int minim, maxim, absMinim;
    treap* left;
    treap* right;
    treap(int key, int priority, int minim, int maxim, int absMinim, treap* left, treap* right){
        this->key = key;
        this->priority = priority;
        this->minim = minim;
        this->maxim = maxim;
        this->absMinim = absMinim;
        this->left = left;
        this->right = right;
    }
}*root, *nill;

void Refresh(treap* &nod){
    if (nod->left == nill && nod->right == nill){
        nod->absMinim = inf;
        nod->maxim = nod->key;
        nod->minim = nod->key;
    }
    else if (nod->left == nill){
        nod->maxim = nod->right->maxim;
        nod->minim = nod->key;
        nod->absMinim = min(nod->right->absMinim, nod->right->minim - nod->key);
    }
    else if (nod->right == nill){
        nod->minim = nod->left->minim;
        nod->maxim = nod->key;
        nod->absMinim = min(nod->left->absMinim, nod->key - nod->left->maxim);
    }
    else{
        nod->maxim = nod->right->maxim;
        nod->minim = nod->left->minim;
        nod->absMinim = min(nod->left->absMinim, nod->right->absMinim);
        nod->absMinim = min(nod->absMinim, nod->key - nod->left->maxim);
        nod->absMinim = min(nod->absMinim, nod->right->minim - nod->key);
    }
}

void RotDr(treap* &nod){
    treap* t = nod->left;
    nod->left = t->right;
    t->right = nod;
    nod = t;
    Refresh(nod->right);
    Refresh(nod);
}

void RotSt(treap* &nod){
    treap* t = nod->right;
    nod->right = t->left;
    t->left = nod;
    nod = t;
    Refresh(nod->left);
    Refresh(nod);
}

void balance(treap* &nod){
    Refresh(nod);
    if (nod->left->key > nod->key){
        RotDr(nod);
    }
    else if (nod->right->key > nod->key){
        RotSt(nod);
    }
}

void Insert(treap* &nod, int &key, int &priority){
    if (nod == nill){
        nod = new treap(key, priority, key, key, inf, nill, nill);
        return;
    }
    if (nod->key > key){
        Insert(nod->left, key, priority);
    }
    Insert(nod->right, key, priority);
    balance(nod);
}

bool Search(treap* &nod, int &key){
    if (nod == nill){
        return false;
    }
    if (nod->key == key){
        return true;
    }
    if (nod->key > key){
        return Search(nod->left, key);
    }
    return Search(nod->right, key);
}

void Erase(treap* &nod, int &key){
    if (nod->key > key){
        Erase(nod->left, key);
    }
    else if (nod->key < key){
        Erase(nod->right, key);
    }
    else{
        if (nod->left == nill && nod->right == nill){
            delete nod;
            nod = nill;
            return;
        }
        else if (nod->left == nill){
            RotSt(nod);
        }
        else if (nod->right == nill){
            RotDr(nod);
        }
        else{
            if (nod->left->priority > nod->right->priority){
                RotDr(nod);
            }
            else{
                RotSt(nod);
            }
        }
        Erase(nod, key);
    }
    Refresh(nod);
}

int main(){
    srand(time(0));
    root = nill = new treap(0, 0, 0, 0, 0, nullptr, nullptr);
    int contor = 0;
    while (fin >> op){
        if (op[0] == 'I'){
            fin >> nr;
            int random = rand() + 1;
            Insert(root, nr, random);
            ++contor;
        }
        else if (op[0] == 'S'){
            fin >> nr;
            if (Search(root, nr)){
                Erase(root, nr);
                --contor;
                continue;
            }
            fout << -1 << "\n";
        }
        else if (op[0] == 'C'){
            fin >> nr;
            fout << Search(root, nr) << "\n";
        }
        else if (op[1] == 'A'){
            if (contor < 2){
                fout << -1 << "\n";
                continue;
            }
            fout << root->maxim - root->minim << "\n";
        }
        else if (op[1] == 'I'){
            if (contor < 2){
                fout << -1 << "\n";
                continue;
            }
            fout << root->absMinim << "\n";
        }
    }
    fin.close();
    fout.close();
    return 0;
}