Cod sursa(job #1457249)

Utilizator retrogradLucian Bicsi retrograd Data 2 iulie 2015 23:40:10
Problema Zeap Scor 30
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Semestrul 2 Marime 3.05 kb
#include <bits/stdc++.h>

using namespace std;
typedef int var;

unordered_map<var, var> Count;
priority_queue< var, vector<var> > Heap;

var diff() {
    while(Count[Heap.top()] <= 0)
        Heap.pop();
    return -Heap.top();
}

struct SkipList {

    #define MAXD 20
    #define INF 1e9+1

    struct nod {
        var val, sz;
        nod **leg;

        nod(var k, var sz) {
            this->sz = sz;
            val = k;
            leg = new nod*[sz];
        }
    };
    typedef nod* pnod;
    pnod root, nill;
    pnod stop[MAXD];

    var MAX, MIN;

    SkipList() {
        root = new nod(-INF, MAXD);
        nill = new nod(INF, 0);
        MAX = -INF, MIN = INF;

        for(var d=0; d<MAXD; d++)
            root->leg[d] = nill;
    }

    pnod find(var val) {
        pnod p = root;
        for(var d=MAXD-1; d>=0; d--) {
            while(p->leg[d]->val < val)
                p = p->leg[d];
            stop[d] = p;
        }
        p = p->leg[0];
        if(p->val == val) return p;
        return NULL;
    }

    void insert(var val) {
        if(find(val)) return;

        var sz = 1;
        var x = rand();
        while(x & 1) sz++, x>>=1;
        sz = min(MAXD, sz);

        pnod p = new nod(val, sz);

        var pred = stop[0]->val,
            succ = stop[0]->leg[0]->val;

        if(pred > -INF && succ < INF) Count[pred - succ] --;
        if(pred > -INF) Count[pred - val] ++, Heap.push(pred - val);
        if(succ < INF) Count[val - succ] ++, Heap.push(val - succ);

        for(var d=0; d<sz; d++) {
            p->leg[d] = stop[d]->leg[d];
            stop[d]->leg[d] = p;
        }

        MAX = max(MAX, val);
        MIN = min(MIN, val);
    }

    bool erase(var val) {
        pnod p = find(val);
        if(p == NULL) return false;


        var pred = stop[0]->val,
            succ = p->leg[0]->val;

        if(pred > -INF && succ < INF) Count[pred - succ] ++, Heap.push(pred - succ);
        if(pred > -INF) Count[pred - val] --;
        if(succ < INF) Count[val - succ] --;

        for(var d=0; d<p->sz; d++) {
            stop[d]->leg[d] = p->leg[d];
        }

        if(MAX == val) MAX = stop[0]->val;
        if(MIN == val) MIN = p->leg[0]->val;

        delete[] p->leg;
        delete p;
        return true;
    }

    void print(var d = 0) {
        for(pnod p = root->leg[d]; p != nill; p = p->leg[d])
            cerr << p->val << " ";
        cerr << endl;
    }
};
SkipList T;

int main() {

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

    var x;

    string tt;
    while(fin>>tt) {
        if(tt == "I") {fin>>x; T.insert(x);}
        if(tt == "S") {fin>>x; if(!T.erase(x)) fout<<"-1\n";}
        if(tt == "C") {fin>>x; fout<<(T.find(x) != NULL)<<'\n';}
        if(tt == "MAX") {fout<<((T.MAX > T.MIN) ? (T.MAX - T.MIN) : -1) << '\n';}
        if(tt == "MIN") {fout<<((T.MAX > T.MIN) ? diff() : -1) << '\n';}
        fout.flush();
        //T.print();
    }
    return 0;
}