Cod sursa(job #2033196)

Utilizator osiaccrCristian Osiac osiaccr Data 6 octombrie 2017 12:09:13
Problema Heapuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.93 kb
#include <fstream>
#define DEF 200001

using namespace std;

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

int v[DEF], _n, n;

class Heap {
public:
    void cut (int k);
    void push (int k);
    int top ();
//private:
    int H[DEF];
    int P[DEF];
    int h;
    void _swap (int a, int b);
    bool _cmp (const int &a, const int &b);
    void _percolate (int k);
    void _sift (int k);
};

void Heap::_swap (int a, int b) {
    swap (H[a], H[b]);
    P[H[a]]= a;
    P[H[b]] = b;
}

bool Heap::_cmp (const int &a, const int &b) {
    return v[a] >= v[b];
}

void Heap::_sift (int k) {
    int son;
    do {
        son = 0;
        if (k * 2 <= h) {
            son = k* 2;
            if (k * 2 + 1 <= h && _cmp (H[2 * k], H[2 * k + 1])) {
                son = 2 * k + 1;
            }
            if (_cmp (H[k], H[son])) {
                son = 0;
            }
        }
        if (son) {
            _swap (H[k], H[son]);
            k = son;
        }
    }
    while (son);
}

void Heap::_percolate (int k) {
    int c = k, p = k/2;
    while (p >= 1 && _cmp (P[p], P[c])) {
        _swap (c, p);
        c = p;
        p /= 2;
    }
}

void Heap::push (int k) {
    H[++h] = k;
    P[++n] = h;
    _percolate (h);
}

void Heap::cut (int k) {
    _swap (k, h);
    h--;
    if (k > 1 && _cmp (H[k / 2], H[k])) {
        _percolate (k);
    }
    else {
        _sift (k);
    }
}

int Heap::top () {
    return H[1];
}

Heap S;

int main () {
    fin >> _n;
    for (int i = 1; i <= _n; i++) {
        int z;
        fin >> z;
        if (z == 1) {
            int x;
            fin >> x;
            v[n + 1] = x;
            S.push (x);
        }
        if (z == 2) {
            int x;
            fin >> x;
            S.cut (x);
        }
        if (z == 3) {
            fout << S.top () << "\n";
        }
    }


    return 0;
}