Cod sursa(job #1258439)

Utilizator CostanMiriamCostan Miriam CostanMiriam Data 8 noiembrie 2014 21:28:11
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.39 kb
#include <fstream>
#include <cstdlib>
#include <ctime>
#define inf (1<<30)

using namespace std;

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

int n,i,x;

char s[5];

int modul (int x) {
    return (x>0?x:-x);
}

struct treap {
    treap *left, *right;
    int k,pr,mi,ma,dimi;
    treap(){};
    treap (int mi, int ma, int dimi, int k, int pr, treap* left, treap* right) {
        this->k=k;
        this->pr=pr;
        this->left=left;
        this->right=right;
        this->mi=mi;
        this->ma=ma;
        this->dimi=dimi;
    }
} *R, *null;

void update (treap* &nod) {
    nod->mi=min(nod->k,nod->left->mi);
    nod->ma=max(nod->k,nod->right->ma);
    nod->dimi=min(min(min(nod->left->dimi,nod->right->dimi),modul(nod->k-nod->left->ma)),modul(nod->k-nod->right->mi));
}

void initializare () {
    R=null=new treap(inf,-inf,inf,0,0,NULL,NULL);
    srand(time(0));
}

void rotleft (treap* &nod) {
    treap *t=nod->left;
    nod->left=t->right;
    t->right=nod;
    nod=t;
    if (nod!=null && nod->right!=null)
        update(nod->right);
}

void rotright (treap* &nod) {
    treap *t=nod->right;
    nod->right=t->left;
    t->left=nod;
    nod=t;
    if (nod!=null && nod->left!=null)
        update(nod->left);
}

void corecteaza (treap* &nod){
    if (nod->left->pr > nod->pr)
        rotleft(nod);
    else
        if (nod->right->pr > nod->pr)
            rotright(nod);
    update(nod);
}

void insereaza (treap* &nod,int k, int pr){
    if (nod==null) {
        nod=new treap ( k,k,inf,k,pr,null,null );
        return;
    }
    if (k < nod->k)
        insereaza (nod->left,k,pr);
    else
        insereaza (nod->right,k,pr);
    corecteaza(nod);
}

bool cauta (treap* &nod, int x) {
    if (nod==null)
        return 0;
    if (x==nod->k)
        return 1;
    if (x < nod->k)
        return cauta(nod->left,x);
    return cauta(nod->right,x);
}

void sterge (treap* &nod, int x) {
    if (nod==null)
        return;
    if (x < nod->k)
        sterge (nod->left,x);
    else {
        if (x > nod->k)
            sterge (nod->right,x);
        else {
            if (nod->left==null&&nod->right==null) {
                delete nod;
                nod=null;
            }
            else
                if (nod->left->pr>nod->right->pr) {
                    rotleft(nod);
                    sterge(nod->right,x);
                }else {
                    rotright(nod);
                    sterge(nod->left,x);
                }

        }
    }
    if (nod!=null)
        update(nod);
}

int main () {

    initializare();

    while (fin>>s) {
        if (s[0]=='I'){
            fin>>x;
            if (!cauta(R,x)) {
                insereaza (R,x,rand()+1);
                n++;
            }
        }else
            if (s[0]=='S'){
                fin>>x;
                if (!cauta(R,x)) {
                    fout<<"-1\n";
                    continue;
                }
                sterge (R,x);
                n--;
            }else
                if (s[0]=='C'){
                    fin>>x;
                    fout<<cauta(R,x)<<"\n";
                }else
                    if (s[1]=='A')
                        fout<<(n<2?-1:R->ma - R->mi)<<"\n";
                    else
                        fout<<(n<2?-1:R->dimi)<<"\n";
    }

    return 0;
}