Cod sursa(job #633846)

Utilizator dany123Florea Daniel dany123 Data 14 noiembrie 2011 22:32:24
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.53 kb
//heapuri: lucru cu indici 14.11.2011
#include<iostream>
#include<fstream>
using namespace std;
const int nmax=200001;
int v[nmax], //v-vectorul cu numerele initiale, nu se modifica
	heap[nmax], //=heapul, va lucra cu indicii elementelor din v[]
	poz[nmax]; //poz[x]=2 => elementul citit al x-lea se afla pe pozitia 2 din heap
int kv=0,kh=0; //contoare pt ^

void afisare() {cout<<'\n'; for (int i=1;i<=kh;++i) cout<<v[heap[i]]<<' ';}

void urca (int indice)
{
	while ( indice>1 && v[heap[indice]]<v[heap[indice/2]] )//cat timp nu suntem in radacina
	{	//si elementul curent e mai mic decat tatal
		swap (heap[indice],heap[indice/2]);//interschimbam indicele elem cur si tata
		poz[heap[indice]]=indice;//elementul intrat al (indice/2)-lea se muta la indice
		poz[heap[indice/2]]=indice/2;//si invers
		indice=indice/2;
	}	
}
void insert (int nr)
{
	v[++kv]=nr; //il punem in vector
	heap[++kh]=kv; //ii punem indicele in heap
	poz[kv]=kh; //intial, indice curent=indice initial
	urca(kh); //trimitem indicele
}

void coboara (int indice)
{
	int fiu,ok;
	do
	{
		fiu=0; ok=0;
		if (indice*2<=kh)
		{
			if ( v[heap[indice*2]] < v[heap[indice]] ) {ok=1; fiu=indice*2;}
			if ( ((indice*2+1)<=kh) && ( v[ heap[indice*2+1] ]  <  v[ heap[indice*2] ] ) 
					&& (v[ heap[indice*2+1] ] < v[heap[indice]]) ) 
				{ok=1; fiu=indice*2+1;} //fiu ia indicele fiului cel mai mare (daca exista)
			if (ok && (v[heap[fiu]] < v[heap[indice]]) )//daca fiul e mai mare at intersch
			{
				swap(heap[fiu],heap[indice]);
				poz[heap[indice]]=indice;
				poz[heap[fiu]]=fiu;
				indice=fiu;
			}
		}
		//afisare();
	}while(ok!=0);//cat timp am gasit un fiu si e mai mare decat elem crt
}
void cut(int y)
{
	int indice = poz[y];
	//afisare();
	swap(heap[kh],heap[indice]); //interschimba elem taiat cu ultimul
	//afisare();
	poz[y]=-1; //nu mai exista
	poz[heap[indice]]=indice;	
	--kh;//heapul se micsoreaza cu 1
	
	//heap[indice_crt]= pozitia initiala a nrului din heap[indice] (=v[heap[indice]])
		
	if (indice>1 && v[heap[indice]]<v[heap[indice/2]])//daca elem crt e mai mic decat tatal
		urca(indice);
	else 
		coboara(indice);//verificam in fct 
	//afisare();
}

int main ()
{
	int n,x,y;
	ifstream fin("heapuri.in");
	ofstream fout("heapuri.out");
	fin>>n;
	for (int i=1;i<=n;++i)
	{
		fin>>x;
		if (x==1) 
		{
			fin>>y;
			insert(y);
		}
		else if (x==2)
		{
			fin>>y;
			cut(y);
		}
		else if (x==3)
		{
			fout<<v[heap[1]]<<'\n';
		}
		
	}
	//afisare();
	fin.close(); fout.close();
	return 0;
}