Cod sursa(job #296368)

Utilizator RegeleUmbrelorPopescu Mihai RegeleUmbrelor Data 4 aprilie 2009 18:15:07
Problema Heapuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb

#include<stdio.h>
#define N 200010

int val[N],poz[N],h[N],n,nh;

inline int tata(int x)
{
	return x>>1;
}

inline int st(int x)
{
	return x<<1;
}

inline int dr(int x)
{
	return (x<<1)+1;
}


void scrie_h()
{
	for(int i=1;i<=nh;++i)
		printf("h[%d]=%d\t",i,val[h[i]]);
	printf("\n");
}

/*
void scrie_poz()
{
	for(int i=1;i<=n;++i)
		printf("poz pe care se afla in heap %d(%d) este %d\t",val[i],i,poz[i]);
	printf("\n");
}
*/

int urca(int x)
{
	int aux=h[x];
	while(tata(x) && (val[aux]<val[h[tata(x)]]))
	{
		poz[h[tata(x)]]=x;
		h[x]=h[tata(x)];
		x=tata(x);
	}
	h[x]=aux;
	return x;
}

int coboara(int x)
{
	int fiu,aux=h[x];
	do{
		fiu=0;
		if(st(x)<=nh)
		{
			fiu=st(x);
			if(dr(x)<=nh && val[h[dr(x)]]<val[h[fiu]])
				fiu=dr(x);
			if(val[h[fiu]]>=val[aux])
				fiu=0;
		}
		if(fiu)
		{
			poz[h[fiu]]=x;
			h[x]=h[fiu];
			x=fiu;
		}
	}while(fiu);
	h[x]=aux;
	return x;
}

int main()
{
	int m,x,tip,aux;
	freopen("heapuri.in","r",stdin);
	freopen("heapuri.out","w",stdout);
	scanf("%d",&m);
	while(m--)
	{
		scanf("%d",&tip);
		if(tip==1)
		{
			scanf("%d",&x);
			val[++n]=x;
			h[++nh]=n;
			poz[n]=urca(nh);
		}
		if(tip==2)
		{
			scanf("%d",&x);
			aux=h[nh--];
			h[poz[x]]=aux;
			poz[aux]=urca(poz[x]);
			poz[aux]=coboara(poz[x]);
			poz[x]=0;
			scrie_h();
		}
		if(tip==3)
			printf("%d\n",val[h[1]]);
	}
	return 0;
}