Cod sursa(job #2517960)

Utilizator PaulTPaul Tirlisan PaulT Data 4 ianuarie 2020 16:19:12
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.43 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

using VI = vector<int>;

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

int Q, n, cnt;
VI v, heap, pos;

void Sift(int k);
void Percolate(int k);
void Insert(int x);			// Inseram valoarea x atat in v, cat si in heap
void Delete(int k);			// Stergem valoarea de pe pozitia k in heap

int main()
{
	int cod, x;
	v = heap = pos = VI(1);
	for (fin >> Q; Q; Q--)
	{
		fin >> cod;
		if (cod == 1)
		{
			fin >> x;
			Insert(x);
		}
		else
			if (cod == 2)
			{
				fin >> x;
				Delete(pos[x]);
			}
			else
				fout << v[heap[1]] << '\n';
	}
	
	fin.close();
	fout.close();
}

void Delete(int k)
{
	swap(heap[k], heap[n]);
	pos[heap[k]] = k;
	heap.pop_back();
	n--;
	
	if (k > 1 && v[heap[k]] < v[heap[k / 2]])
		Percolate(k);
	else
		Sift(k);
}

void Insert(int x)
{
	n++;
	cnt++;
	v.emplace_back(x);
	heap.emplace_back(cnt);
	pos.emplace_back(n);
	Percolate(n);
}

void Percolate(int k)
{
	while (k > 1 && v[heap[k / 2]] > v[heap[k]])
	{
		swap(heap[k], heap[k / 2]);
		pos[heap[k]] = k;
		pos[heap[k / 2]] = k / 2;
		k /= 2;
	}
}

void Sift(int k)
{
	int son;
	do
	{
		son = 0;
		if (2 * k <= n)
		{
			son = 2 * k;
			if (2 * k + 1 <= n && v[heap[2 * k + 1]] < v[heap[2 * k]])
				son = 2 * k + 1;
			if (v[heap[son]] >= v[heap[k]])
				son = 0;
		}
		if (son)
		{
			swap(heap[k], heap[son]);
			pos[heap[k]] = k;
			pos[heap[son]] = son;
			k = son;
		}
	} while (son);
}