Cod sursa(job #472471)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 25 iulie 2010 01:49:57
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.01 kb
#include <fstream>
#include <iostream>
#define NMAX 200001
//#define INF 0x3f3f3f3f

using namespace std;
//variabile globale:
struct heap
{
	int valoare;
	int indice;
	
}H[NMAX];

int poz[NMAX];
int Lung,Introd;
//functia de interschimbare supraincarcata pentru int si heap
inline void schimb(heap &a, heap &b)
{
	heap aux;
	aux=a;
	a=b;
	b=aux;
}

inline void schimb(int &a,int &b)
{
	int aux;
	aux=a;
	a=b;
	b=aux;
}

//functia de introducere a unui nou element in heap
void push_up(int val)
{
	int l;
	Lung++;
	Introd++;
	H[Lung].valoare=val;
	H[Lung].indice=Introd;
	poz[Introd]=Lung;
	l=Lung;
	while(H[l].valoare<H[l/2].valoare)
	{
		schimb(poz[H[l].indice], poz[H[l/2].indice]);
//		schimb(H[l].valoare,H[l/2].valoare);
//		schimb(H[l].indice,H[l/2].indice);
		schimb(H[l],H[l/2]);
		l=l/2;
	}
}

//functia de coborare in heap
void push_down(int l)
{
	if((l*2+1<=Lung) && (H[l*2+1].valoare<H[l*2].valoare) && (H[l].valoare>H[l*2+1].valoare))
	{
		schimb(H[l*2+1],H[l]);
		schimb(poz[H[l*2+1].indice],poz[H[l].indice]);
		push_down(l*2+1);
	}
	else if((l*2+1<=Lung) && (H[l*2+1].valoare>H[l*2].valoare) && (H[l].valoare>H[l*2].valoare))
	{
		schimb(H[l*2],H[l]);
		schimb(poz[H[l*2].indice],poz[H[l].indice]);
		push_down(l*2);
	}
	else if((l*2==Lung) && (H[l*2].valoare<H[l].valoare))
	{
		schimb(H[l*2],H[l]);
		schimb(poz[H[l*2].indice],poz[H[l].indice]);
	}
	
}
//functia de relaxare a heapului dupa stergere
void relax(int l)
{
	if(H[l].valoare<H[l/2].valoare)
		while(H[l].valoare<H[l/2].valoare)
		{
		schimb(poz[H[l].indice], poz[H[l/2].indice]);
//		schimb(H[l].valoare,H[l/2].valoare);
//		schimb(H[l].indice,H[l/2].indice);
		schimb(H[l],H[l/2]);
		l=l/2;
		}
	else push_down(l);
	
}

//functia de stergere din heap a elementului cu pozitia l
void sterge_pozitie(int l)
{
	/*
	Fara verificarea stergerii ultimului element acesta va fi 
	initializat cu 0 si va fi urcat pe prima pozitie a heapului
	->eroare
	*/
	if(l!=Lung)//daca stergem alt element inafara de ultimul
	{
		schimb(H[l],H[Lung]);
		schimb(poz[H[l].indice],poz[H[Lung].indice]);
		H[Lung].indice=0;
		H[Lung].valoare=0;
		poz[H[Lung].indice]=0;
		Lung--;
		relax(l);
	}
	else Lung--;//daca stergem pe ultimul
}

//functia de citire a datelor
void citire()
{
	ifstream fin("heapuri.in");
	ofstream fout("heapuri.out");
	int N,x,y;
	fin>>N;
	for(int i=1;i<=N;i++)
	{
		fin>>x;
		switch(x)
		{
		case(1):
			{
				fin>>y;
				push_up(y);
				break;
			}
		case(2):
			{
				fin>>y;
				sterge_pozitie(poz[y]);
				break;
			}
		case(3):
			{
				fout<<H[1].valoare<<"\n";
				break;
			}
		}
	}
	fin.close();
	fout.close();
}

//main + debug
int main(int argc, char *argv[])
{
	citire();
//debug:	
	/*	
	for(int i=1;i<=Lung;i++)
		cout<<H[i].valoare<<" ";
	cout<<"\n";
	for(int i=1;i<=Lung;i++)
		cout<<H[i].indice<<" ";
	cout<<"\n";
	for(int i=1;i<=Introd;i++)
		cout<<poz[i]<<" ";
	cout<<"\n";
	cout<<Lung<<endl;
	cout<<Introd<<endl;
	*/
}