Cod sursa(job #3129050)

Utilizator Maria_VerdesVerdes Maria-Ioana Maria_Verdes Data 12 mai 2023 13:46:17
Problema Heapuri Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.74 kb
#include <fstream>
#include <vector>

using namespace std;

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

int main()
{
    int n, optiune, element;
    vector <int> v; //tine minte el in ordinea in care vin
    vector <int> poz; //tine pozitia el de la indicele i din v in heap
    vector <pair<int, int>> heap; //tine in ordine elementele din heap + pozitiile lor in vectorul initial
    v.push_back(0);
    heap.push_back(make_pair(0, 0));
    poz.push_back(0);
    f >> n;
    for(int i = 1; i <= n; i++)
    {
        f >> optiune;
        switch(optiune)
        {
        case 1:
            {
                f >> element; //valoarea care trebuie inserata in heap
                //o introducem pe ultima pozitie si o promovam pana la locul potrivit
                heap.push_back(make_pair(element, v.size()));
                v.push_back(element);
                int pos = heap.size() - 1;
                poz.push_back(pos);
                while(heap[pos].first < heap[pos / 2].first && pos > 1)
                //cat timp nodul nostru are o val mai mica decat tatal sau ii interschimbam
                {
                    int poz_tata = heap[pos / 2].second;
                    int poz_fiu = heap[pos].second;
                    swap(poz[poz_fiu], poz[poz_tata]);
                    swap(heap[pos], heap[pos / 2]);
                    pos = pos / 2;
                }
                break;
            }
        case 2:
            {
                f >> element; //indicele valorii pe care vrem sa o stergem
                int pos = poz[element]; //pozitia nodului pe care vr sa-l stergem din heap
                heap[pos] = heap[heap.size() - 1]; //inlocuim valoarea pe care vrem sa o stergem cu ultima din heap
                heap.erase(heap.begin() + heap.size()); //stergem ultimul element
                //acum trebuie sa facem cernere sau promovare
                if(heap[pos].first < heap[pos / 2].first && pos > 1)
                {
                    //promovare
                     while(heap[pos].first < heap[pos / 2].first && pos > 1)
                    {
                        int poz_tata = heap[pos / 2].second;
                        int poz_fiu = heap[pos].second;
                        swap(poz[poz_fiu], poz[poz_tata]);
                        swap(heap[pos], heap[pos / 2]);
                        pos = pos / 2;
                    }
                }
                else {
                    //cernere
                    while((pos * 2 < heap.size() && heap[pos].first > heap[pos * 2].first) ||
                          (pos * 2 + 1 < heap.size() && heap[pos].first > heap[pos * 2 + 1].first))
                    {
                        if(pos * 2 < heap.size() && heap[pos].first > heap[pos * 2].first)
                        {
                            int poz_fiu = heap[pos * 2].second;
                            int poz_tata = heap[pos].second;
                            swap(poz[poz_fiu], poz[poz_tata]);
                            swap(heap[pos], heap[pos * 2]);
                            pos = pos * 2;
                        }
                        else {
                            int poz_fiu = heap[pos * 2 + 1].second;
                            int poz_tata = heap[pos].second;
                            swap(poz[poz_fiu], poz[poz_tata]);
                            swap(heap[pos], heap[pos * 2 + 1]);
                            pos = pos * 2 + 1;
                        }
                    }
                }
                break;
            }
        case 3:
            {
                g << heap[1].first << endl;
                break;
            }
        }
    }
    f.close();
    g.close();
    return 0;
}