Cod sursa(job #2621798)

Utilizator lauratenderLaura Tender lauratender Data 30 mai 2020 19:30:45
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.22 kb
#include <fstream>
#include <iostream>
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] = {x, cnt};
    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 * 2 > nr_elemente) // elementul nu are niciun fiu
        return;
    if (poz * 2 + 1 > nr_elemente){
        if(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)
{
    int poz = intrat[i];

    std::swap(arbore[nr_elemente], arbore[poz]);
    intrat[arbore[poz].second] = poz;

    --nr_elemente;
    if (poz <= nr_elemente){
        Urca(poz);
        Coboara(poz);
    }
}
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";
    /*for (int i=1; i <= heap.cnt; ++i)
        out << heap.intrat[i] << " ";
    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 ( x == 10172)
                //out<<heap;
        }
        if (op == 2)
        {
            int x;
            in >> x;
            //if (x==14)
                //out<<heap;
            heap.Stergere(x);
            //if (x==14 || x==22)
                //out<<heap;
        }
        if (op == 3)
        {
            out << heap.Minim()<<"\n";
        }
    }
    //out<<heap;
    return 0;
}