Pagini recente » Cod sursa (job #2571304) | Cod sursa (job #2261578) | Cod sursa (job #1356222) | Cod sursa (job #678260) | Cod sursa (job #2924372)
#include <fstream>
#include <cassert>
const int nMax = 200001;
struct nod {
int val;
int idx;
bool operator<(const nod &nodNou) const {
return val < nodNou.val;
}
bool operator>(const nod &nodNou) const {
return val > nodNou.val;
}
} heap[nMax];
int lastPozHeap = 0;
int idx[nMax];
int coIdx;
using namespace std;
void urcare(int pozi) {
while (pozi > 1) { ///cat timp nu am ajuns in radacina heapului
if (heap[pozi / 2] > heap[pozi]) { ///daca inca nu e respectata proprietatea de heap
idx[heap[pozi].idx] = pozi / 2; ///refacem pozitia elementelor in vectorul idx
idx[heap[pozi / 2].idx] = pozi;
///interschimbam fiul cu tatal
swap(heap[pozi], heap[pozi / 2]);
pozi /= 2;
} else {
break; ///altfel, am terminat
}
}
}
void coborare(int pozi) {
while (pozi * 2 <= lastPozHeap) { ///cat timp mai avem cel putin un fiu
int pozCopilMin;
if (pozi * 2 + 1 > lastPozHeap) { ///daca avem doar un fiu stang, acela este candidatul
pozCopilMin = pozi * 2;
} else { ///altfel, luam ca candidat fiul cu valoare minima
if (heap[pozi * 2] < heap[pozi * 2 + 1]) { ///op de comparare supraincarcat pt valuare
pozCopilMin = pozi * 2;
} else {
pozCopilMin = pozi * 2 + 1;
}
}
///daca fiul cu valoare minima e mai mic decat tatal, ii interschimbam
if (heap[pozi] > heap[pozCopilMin]) {
///refacem pozitile noi in vectorul idx
idx[heap[pozi].idx] = pozCopilMin;
idx[heap[pozCopilMin].idx] = pozi;
///interschimbam
swap(heap[pozi], heap[pozCopilMin]);
pozi = pozCopilMin;
} else {
break;///altfel, am terminat
}
}
}
void inserare(int nr) {
lastPozHeap += 1;///adaugam in heap pe ultima pozitie (heapul este mereu continuu)
coIdx += 1; ///vectorul idx va avea in total cate elem unice s-au adaugat si pt elem nesterse va stii pe ce pozitie se gasesc in heapul heap
heap[lastPozHeap].val = nr; ///nr adaugat
heap[lastPozHeap].idx = coIdx; ///aceasta valoare ramane constanta mereu
idx[coIdx] = lastPozHeap; ///noul elem se afla acum pe ultima pozitie in heap
urcare(lastPozHeap); ///refacem structura de min-Heap
}
void stergere(int idxi) {
int pozi = idx[idxi]; /// pozitia in heap la care se afla elem intrat al idxi in multime
heap[pozi] = heap[lastPozHeap]; ///il suprascriem cu elem aflat pe ultima pozitie in vectorul heap
lastPozHeap--;///(pt ca nu are voie sa aiba goluri) si il stergem apoi scazand nr de elemente in heap
///elem poate doar sa urce sau doar sa coboare pt a reface structura de heap
if (heap[pozi].val < heap[pozi / 2].val && pozi > 1)
urcare(pozi);
else
coborare(pozi);
}
int main() {
int n, op;
ifstream fin("heapuri.in");
ofstream fout("heapuri.out");
fin >> n;
for (int i = 0; i < n; i++) {
fin >> op;
switch (op) {
case 1: {
int nr;
fin >> nr;
inserare(nr);
break;
}
case 2: {
int idxi;
fin >> idxi;
stergere(idxi);
break;
}
case 3: {
fout << heap[1].val << '\n'; ///elem minim se afla in min-Heap in radacina
break;
}
default:
assert(false);
}
}
fin.close();
fout.close();
return 0;
}