Cod sursa(job #2739306)

Utilizator MateiDorian123Nastase Matei MateiDorian123 Data 7 aprilie 2021 18:24:57
Problema Heapuri Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.85 kb
#include <bits/stdc++.h>

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

vector<int> h, aux; /// h este heap-ul aux este un vector cu ordinea initiala a elementelor care ne ajuta la operatia 2
int n;

inline int father(int nod){ /// functia returneaza indicele tatalui lui nod
    return nod / 2;
}

inline int left(int nod){ /// functia returneaza indicele fiului stanga a lui nod
    return nod * 2;
}

inline int right(int nod){ /// functia returneaza indicele fiului dreapta a lui nod
    return nod * 2 + 1;
}

void sift(vector<int>& h, int k){ /// coboram nodul k
    int son;
    int lg = h.size() - 1;
    do{
        son = 0;
        /// alegem un fiu mai mic decat tatal
        if(left(k) <= lg){ /// daca exista fiu stang
            son = left(k);

            if(right(k) <= lg) /// daca exista si fiu la dreapta il alegem pe cel mai mic
                if(h[right(k)] < h[son])
                    son = right(k);

            if(h[son] >= h[k])
                son = 0; /// tatal e mai mic decat cel mai mic fiu -> avem heap bun -> ne oprim
        }

        if(son){
            swap(h[k], h[son]);
            k = son;
        }


    }while(son);

}

void percolate(vector<int>& h, int k){ /// ridicam nodul k pana la pozitia lui din heap

    int key = h[k];
    while(k > 1 && key < h[father(k)]){ /// cat timp nu am ajuns in radacina si nodul curent e mai mic decat tatal sau
        h[k] = h[father(k)];
        k = father(k);
    }

    h[k] = key;
}

void Insert(vector<int>& h, int x){
    ///functia insereaza in heap valoarea x
    /// inseram la finalul vectorului si dupa facem percolate pentru a pastra structura de heap
    h.push_back(x);
    percolate(h, h.size()-1);


}

void Extract(vector<int>& h, int x){/// functia sterge primul nod cu valoarea x din heap

    int poz;
    /// cautam pozitia lui x in heap
    for(int i = 1; i < h.size(); i ++)
        if(h[i] == x){
            poz = i;
            break;
        }

    ///stergem elementul de pe pozitia poz
    h[poz] = h[h.size() - 1];
    h.pop_back();

    if(poz > 1 && h[poz] < h[father(poz)]) /// daca este mai mic decat tatal, fiul trebuie promovat
        percolate(h, poz);
    else
        sift(h, poz);
}

int main()
{   int cmd, x, poz;
    fin>>n;

    h.push_back(0); /// am pus un element pe prima pozitie pentru a avea indexarea de la 0
    aux.push_back(0);

    for(int i = 1; i <= n; i ++){
        fin>>cmd;
        if(cmd == 1){
            fin>>x;
            aux.push_back(x);
            Insert(h, x);
        }

        else if(cmd == 2){
            fin>>poz;
            x = aux[poz];
            Extract(h, x);
        }

        else fout<<h[1]<<"\n";
    }

    //for(int i = 1; i<= h.size() - 1;i++)
        //cout<<h[i]<<" ";

    return 0;
}