Pagini recente » Cod sursa (job #2394187) | Cod sursa (job #2048795) | Cod sursa (job #2383586) | Cod sursa (job #2466089) | Cod sursa (job #2895746)
#include <fstream>
#include <utility>
#include <vector>
std::ifstream fin("heapuri.in");
std::ofstream fout("heapuri.out");
int N, Op, Val, Dim, Ord, Poz;
std::vector<int> Pozitii(200001);
std::vector< std::pair<int, int> > Heap(200001);
void percolate()
{
while (Poz > 1 && Heap[Poz].first < Heap[Poz / 2].first)
{
std::swap(Heap[Poz], Heap[Poz / 2]);
std::swap(Pozitii[Heap[Poz].second], Pozitii[Heap[Poz / 2].second]);
Poz /= 2;
}
// Cat timp nu ma aflu in varful heap-ului si fiul este mai mic decat
// tatal, urc fiul in locul tatalui.
}
void sift()
{
int Fiu;
do
{
Fiu = 0;
// Plec de la presupunerea ca nodul nu mai are niciun fiu si
// coborarea se opreste.
if (Poz * 2 <= Dim)
{
Fiu = Poz * 2;
// Daca nodul are fiu stang, atunci acesta este selectat.
if (Poz * 2 + 1 <= Dim && Heap[Poz * 2 + 1].first < Heap[Poz * 2].first)
{
Fiu = Poz * 2 + 1;
// Daca nodul are si fiu drept si fiul drept este mai mic decat
// fiul stang, atunci fiul drept este preferat si este selectat
// in locul fiului stang.
}
if (Heap[Fiu].first >= Heap[Poz].first)
{
Fiu = 0;
// Daca cel mai mic dintre fii este mai mare sau egal cu tatal,
// atunci niciun fiu nu mai este selectat si coborarea se opreste.
}
}
if (Fiu)
{
std::swap(Heap[Poz], Heap[Fiu]);
std::swap(Pozitii[Heap[Poz].second], Pozitii[Heap[Fiu].second]);
Poz = Fiu;
// Daca unul din fii a fost selectat, atunci cobor tatal
// in locul fiului si continui.
}
} while (Fiu);
}
void inserare()
{
Dim++; // Incrementez dimensiunea heap-ului.
Ord++; // Incrementez numarul de elemente inserate.
// Inserez elementul in heap pe ultima pozitie.
Heap[Dim].first = Val; // Valoarea elementului.
Heap[Dim].second = Ord; // Al catelea a fost inserat in heap.
Pozitii[Ord] = Dim; // Pozitia pe care a fost inserat elementul in heap.
Poz = Dim;
percolate();
// Urc elementul pana la locul lui, daca este cazul.
}
void stergere()
{
Poz = Pozitii[Val];
// Determin pe ce pozitie se afla elementul care trebuie sters.
std::swap(Heap[Poz], Heap[Dim]);
std::swap(Pozitii[Heap[Poz].second], Pozitii[Heap[Dim].second]);
// Sterg elementul punand in locul lui ultimul element din heap
// si pe el pe ultima pozitie.
Dim--; // Decrementez dimensiunea heap-ului.
if (Heap[Poz].first < Heap[Poz / 2].first)
percolate();
// Daca elementul pus in locul celui sters este mai mic
// decat tatal, atunci il urc.
else
sift();
// Altfel, il cobor.
}
int main()
{
fin >> N;
for (int i = 0; i < N; i++)
{
fin >> Op;
switch (Op)
{
case 1:
fin >> Val;
inserare();
break;
case 2:
fin >> Val;
stergere();
break;
case 3:
fout << Heap[1].first << '\n';
break;
default:
break;
}
}
}