Cod sursa(job #1417399)

Utilizator daniel.grosuDaniel Grosu daniel.grosu Data 10 aprilie 2015 11:52:25
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.93 kb
/*
Min heap implementation on functions.

TODO: Min Heap implematation on templates
*/
#include <iomanip>
#include <fstream>

#define NMAX 200001
using namespace std;

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

typedef int Heap[NMAX]; // Heap de iteratori a vectorilor de valori
int q[NMAX]; // Vector de valori
int Pos[NMAX]; // Pozitia nodurilor in heap pentru stergere in logn

inline int father(int node)
{
    return node/2;
}

inline int left_son(int node)
{
    return 2*node;
}

inline int right_son(int node)
{
    return 2*node+1;
}

inline int head(Heap H)
{
    return H[1];
}

void print(Heap H, int N, int K, int D)
{
	if(H[K])
	{
		if(right_son(K)<=N)
			print(H, N, right_son(K), D+1);
		fout<<setw(4*D)<<"";
		fout<<q[H[K]]<<endl;
		if(left_son(K)<=N)
			print(H, N, left_son(K), D+1);
		
	}
}

void down(Heap H, int N, int K) // Descendenta nodului pana la stabilirea echilibrului
{
    int son,a,b;
    do{
        son=0;
        a=left_son(K);
        b=right_son(K);
        
        if(a<=N){
            son=a;
            if(b<=N && q[H[b]]<=q[H[a]]) // Comparam valorile din vectorul de valori
                son=b;
            // Alegem fiul cel mai mare, in limita N.
            if(q[H[son]]>=q[H[K]]) //Daca chiar fiul cel mai mic este mai mare, nu este nevoie de a cerne mai departe
                son=0;
        }
        
        // Daca exista un fiu cu o valoare mai mica interschimbam
        
        if(son)
        {
            swap(H[K], H[son]);
			Pos[H[K]]=K;
			Pos[H[son]]=son;
            K=son; // Cernem mai departe recursiv
        }
    }while(son);
}

void up(Heap H, int K, int N) //Urcam nodul pana se stabileste echilibrul
{
    int key=H[K];
    
    while(K>1 && q[key]<q[H[father(K)]]) // Urcam in arbore recursiv
    {
        H[K]=H[father(K)];
        Pos[H[K]]=K;
        K=father(K);
    }
    
    H[K]=key; // La ultimul nod urcat atribuim cheia
    Pos[key]=K;
}

void build_heap(Heap H, int N) // Sortam heap-ul
{
    for(int i=N/2; i>0; --i)
        down(H,N,i);
}

void erase(Heap H, int& N, int K) // Stergerea unui element in O(logn), K - pozitia K in Heap
{
	H[K]=H[N];
    --N;
    if(K>1 && q[H[K]]<q[H[father(K)]])
        up(H, N, K);
    else
        down(H, N, K);
}

void insert(Heap H, int& N, int key)
{
    H[++N]=key;
    Pos[H[N]]=N;
    up(H, N, N);
}

Heap A; int N; // Heap vector and heap size

int t,a,b,i;

int main()
{
    fin>>t;
    i=1;
    while(t--)
    {
    	fin>>a;
    	
		switch(a)
		{
			case 1:
				fin>>b;
				q[i]=b;
				insert(A, N, i);
				++i;
				break;
			case 2:
				fin>>b;
				erase(A, N, Pos[b]);
				break;
			case 3:
//				fout<<"----BEGIN_PRINT----N="<<N<<endl;
//				print(A, N, 1, 0);
//				fout<<"----END_PRINT---------"<<endl;
				fout<<q[head(A)]<<"\n";
				break;
		}
	}
    
    return 0;
}