Cod sursa(job #2621725)

Utilizator lauratenderLaura Tender lauratender Data 30 mai 2020 18:06:51
Problema Heapuri Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.1 kb
#include <fstream>

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

class Heap
{
    static const int N = 200000;
    int cnt; // numarul de elemente intrate
    std::pair<int, int>* arbore;
    int intrat [N+2];
    int nr_elemente;
    void Urca(int);
    void Coboara (int);
public:
    Heap(){
        nr_elemente = 0;
        arbore = new std::pair<int, int> [N+2];
        cnt = 0;
    }
    void Inserare (int);
    void Stergere (int);
    int Minim();
    ~Heap();
    friend std::ostream& operator << (std::ostream&, Heap&);
};
void Heap::Inserare(int x)
{
    nr_elemente++;
    cnt ++;
    arbore [nr_elemente].first = x; //valoarea elementului
    arbore [nr_elemente].second = cnt; //al catalea intrat este elementul
    intrat [cnt] = nr_elemente; // intrat[i] reprezinta pozitia pe care se afla al i-lea element intrat
    Urca(nr_elemente);
}
void Heap::Urca (int poz)
{
    while ( poz / 2 > 0 && arbore[poz/2].first > arbore[poz].first){
        std::swap(arbore[poz/2], arbore[poz]);
        intrat[arbore[poz/2].second] = poz/2;
        intrat [arbore[poz].second] = poz;
        poz/=2;
    }
}
void Heap::Coboara (int poz)
{
    if (poz < nr_elemente)
    {
        if (poz*2 > nr_elemente) // elementul nu are niciun fiu
            return;
        if (poz*2 + 1 > nr_elemente && arbore[poz*2].first < arbore[poz].first) //elementul are un singur fiu si fiul este mai mic
        {
            std::swap(arbore[poz], arbore[poz*2]);
            intrat[arbore[poz*2].second] = poz*2;
            intrat[arbore[poz].second] = poz;
            return;
        }
        if ( arbore[poz] < arbore[poz*2] && arbore[poz] < arbore[poz*2+1])
            return;
        int poz_fiu_min;
        if (arbore[poz*2].first <= arbore[poz*2 + 1].first)
            poz_fiu_min = poz * 2;
        else
            poz_fiu_min = poz * 2 + 1;
        std::swap(arbore[poz], arbore[poz_fiu_min]);
        intrat[arbore[poz_fiu_min].second] = poz_fiu_min;
        intrat[arbore[poz].second] = poz;
        Coboara(poz_fiu_min);
    }
}
void Heap::Stergere(int i)
{
    if ( intrat[i] != nr_elemente)
    {
    std::swap(arbore[nr_elemente], arbore[intrat[i]]);
    intrat[arbore[intrat[i]].second] = intrat[i];
    }
    --nr_elemente;
    if (intrat[i] <= nr_elemente)
        Urca(intrat[i]);
    Coboara(intrat[i]);
}
int Heap::Minim()
{
    return arbore[1].first;
}
Heap::~Heap()
{
    delete[] arbore;
}
std::ostream& operator<< (std::ostream& o, Heap& heap)
{
    for (int i=1; i <= heap.nr_elemente; ++i)
        out << heap.arbore[i].first << " ";
    out << "\n";
    return o;
}

int main()
{
    Heap heap;
    int q, op;
    in >> q;
    for (int i = 0; i < q; ++i)
    {
        in >> op;
        if (op == 1)
        {
            int x;
            in >> x;
            heap.Inserare(x);
        }
        if (op == 2)
        {
            int x;
            in >> x;
            heap.Stergere(x);
        }
        if (op == 3)
        {
            out << heap.Minim()<<"\n";
        }
    }
    return 0;
}