Cod sursa(job #1096816)

Utilizator mihai995mihai995 mihai995 Data 2 februarie 2014 17:02:22
Problema Heapuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 3.04 kb
#include <fstream>
using namespace std;

class BinomialHeap{
    struct Node{
        int key, grad;
        Node *bro, *son;

        Node(int key, int grad, Node* bro, Node* son) : key(key), grad(grad), bro(bro), son(son) {};
    };
    Node* root;

    Node* findMin(){
        Node* best = root;
        for (Node* p = root ; p -> bro ; p = p -> bro)
            if (p -> bro -> key < best -> bro -> key)
                best = p;
        return best;
    }

    Node* simpleMerge(Node* st, Node* dr){
        if (st -> key < dr -> key){
            st -> bro = dr -> bro;
            dr -> bro = st -> son;
            st -> son = dr;
            st -> grad++;
            return st;
        }
        st -> bro = dr -> son;
        dr -> son = st;
        dr -> grad++;
        return dr;
    }

    void merge(Node* R){
        if (R -> bro == NULL)
            return;
        if (root -> bro == NULL){
            delete root;
            root = R;
            return;
        }
        Node* neoRoot = new Node(0, 0, NULL, NULL), *pos = neoRoot;
        Node *p, *q;
        for (p = root -> bro, q = R -> bro ; p && q ; )
            if (!q || (p && p -> grad > q -> grad)){
                pos = pos -> bro = p;
                p = p -> bro;
            } else {
                pos = pos -> bro = q;
                q = q -> bro;
            }
        for (Node* P = neoRoot ; P -> bro -> bro ; )
            if (P -> bro -> grad == P -> bro -> bro -> grad)
                P -> bro = simpleMerge(P -> bro, P -> bro -> bro);
            else
                P = P -> bro;
        if (p)
            pos -> bro = p;
        else
            pos -> bro = q;
        delete root;
        delete R;
        root = neoRoot;
    }

public:
    BinomialHeap(){
        root = new Node(0, 0, NULL, NULL);
    }

    void insert(int x){
        merge( new Node(0, 0, new Node(x, 1, NULL, NULL), NULL) );
    }

    int getTop(){
        return findMin() -> bro -> key;
    }

    void popTop(){
        Node* pos = findMin();
        Node* aux = pos -> bro;
        pos -> bro = pos -> bro -> bro;
        aux -> bro = aux -> son;
        merge(aux);
    }

    bool isEmpty(){
        return root -> bro == NULL;
    }

    void merge(BinomialHeap B){
        return merge(B.root);
    }
};

const int N = 200000;

BinomialHeap A, B;
int v[N];

ifstream in("heapuri.in");
ofstream out("heapuri.out");

void insert(int x){
    A.insert(x);
    v[++v[0]] = x;
}

void erase(int x){
    B.insert(v[x]);
}

int getMin(){
    while (!B.isEmpty() && A.getTop() == B.getTop()){
        A.popTop();
        B.popTop();
    }
    return A.getTop();
}

int main(){
    int times, type, x;
    in >> times;
    while (times--){
        in >> type;
        if (type == 1){
            in >> x;
            insert(x);
        }
        if (type == 2){
            in >> x;
            erase(x);
        }
        if (type == 3)
            out << getMin() << "\n";
    }
    return 0;
}