Cod sursa(job #2610085)

Utilizator KPP17Popescu Paul KPP17 Data 4 mai 2020 12:53:56
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.94 kb
#define fisier "heapuri"
#include <fstream>
std::ifstream in(fisier ".in");
std::ofstream out(fisier ".out");

const int N = 200000;

struct Nod {int val, id;} heap[N];
int n, poz_pt[N], next_id, elemente;



inline Nod& nod_pt(int id) {return heap[poz_pt[id]];}
inline int& val_pt(int id) {return nod_pt(id).val;}

inline int poz_copil_st_pt(int id) {return (poz_pt[id] + 1 << 1) - 1;}
inline Nod& nod_copil_st_pt(int id) {return heap[poz_copil_st_pt(id)];}
inline int& val_copil_st_pt(int id) {return heap[poz_copil_st_pt(id)].val;}
inline int& id_copil_st_pt(int id) {return heap[poz_copil_st_pt(id)].id;}

inline int poz_copil_dr_pt(int id) {return poz_copil_st_pt(id) + 1;}
inline Nod& nod_copil_dr_pt(int id) {return heap[poz_copil_dr_pt(id)];}
inline int& val_copil_dr_pt(int id) {return heap[poz_copil_dr_pt(id)].val;}
inline int& id_copil_dr_pt(int id) {return heap[poz_copil_dr_pt(id)].id;}

inline int poz_parinte_pt(int id) {return (poz_pt[id] + 1 >> 1) - 1;}
inline Nod& nod_parinte_pt(int id) {return heap[poz_parinte_pt(id)];}
inline int& val_parinte_pt(int id) {return nod_parinte_pt(id).val;}
inline int& id_parinte_pt(int id) {return nod_parinte_pt(id).id;}

inline int poz_copil_mai_mic_pt(int id) {return val_copil_st_pt(id) < val_copil_dr_pt(id)? poz_copil_st_pt(id): poz_copil_dr_pt(id);}
inline Nod& nod_copil_mai_mic_pt(int id) {return heap[poz_copil_mai_mic_pt(id)];}
inline int& val_copil_mai_mic_pt(int id) {return heap[poz_copil_mai_mic_pt(id)].val;}
inline int& id_copil_mai_mic_pt(int id) {return heap[poz_copil_mai_mic_pt(id)].id;}

inline int poz_ultimul() {return elemente - 1;}
inline Nod& nod_ultimul() {return heap[poz_ultimul()];}
inline int& val_ultimul() {return heap[poz_ultimul()].val;}
inline int& id_ultimul() {return heap[poz_ultimul()].id;}

inline bool este_frunza(int id) {return poz_copil_st_pt(id) > poz_ultimul();}
inline bool are_doi_copii(int id) {return poz_copil_dr_pt(id) <= poz_ultimul();}
inline bool este_ultimul(int id) {return poz_pt[id] == poz_ultimul();}





void interschimba(int id_a, int id_b)
{
    std::swap(nod_pt(id_a), nod_pt(id_b));
    std::swap(poz_pt[id_a], poz_pt[id_b]);
}

void integreaza(int id)
{
    //out << "integrez " << id << std::endl;

    if (poz_pt[id] && val_parinte_pt(id) > val_pt(id))
    {
        interschimba(id, id_parinte_pt(id));
        integreaza(id);
    }

}

void _pop(int id)
{
    //out << "_scot " << id << std::endl;

    if (!este_ultimul(id))
    {
        //out << "    nu este ultimul" << std::endl;
        if (este_frunza(id))
        {
            //out << "    este frunza" << std::endl;
            int id_ex_ultimul = id_ultimul();
            interschimba(id, id_ex_ultimul);
            integreaza(id_ex_ultimul);
        }
        else if (are_doi_copii(id))
        {
            //out << "    are doi copii" << std::endl;
            interschimba(id, id_copil_mai_mic_pt(id));
            _pop(id);
        }
        else // ia ghici
        {
            //out << "    are un copil" << std::endl;
            interschimba(id, id_copil_st_pt(id));
            _pop(id);
        }
    }
}

void pop(int id)
{
    //out << "scot " << id << std::endl;
    _pop(id);
    elemente--;
}


int main()
{
    in >> n;

    while (n--)
    {
        int op, x; in >> op;
        if (op != 3)
            in >> x;

        //out << "[";

        //for (int poz = 0; poz < elemente; poz++)
        //{
        //    out << heap[poz].val << ' ';
        //}
        //out << "]\n";

        switch (op)
        {
            case 1:

                heap[elemente] = {x, next_id};
                poz_pt[next_id] = elemente++;
                integreaza(next_id++);

                break;

            case 2:

                pop(x - 1);

                break;

            case 3:

                out << heap->val << '\n';

                break;
        }
    }
}