Cod sursa(job #322584)

Utilizator tamas_iuliaTamas Iulia tamas_iulia Data 9 iunie 2009 11:17:25
Problema Heapuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
#include <stdio.h>
#define Nmax 200005

long h[Nmax],poz[Nmax],a[Nmax]; // poz[i]=x => al i-lea elem a ajuns pe poz x
long i,j,op,x,l=0,q,nr=0;

long tata(long k){
	return k/2;
}
long fiust(long k){
	return 2*k;
}
long fiudr(long k){
	return 2*k+1;
}

void UP(long k){ // k e mai mic ca tasu
	long aux;

   while(k>1 && a[h[k]] < a[h[tata(k)]]){
      aux=h[k];
      h[k]=h[tata(k)];
      h[tata(k)]=aux;;

      poz[h[k]]=k;
      poz[h[tata(k)]]=tata(k);
      k=tata(k);
   }
}

void DOWN(long k){ // k e mai mare decat fisu
    long son,aux;
    do{
      son=0;
    	if(fiust(k) <=l){
      	 son=fiust(k);
          if(fiudr(k) <=l && a[h[fiudr(k)]]<a[h[fiust(k)]])
             son = fiudr(k);
          if( a[h[son]] >= a[h[k]] ) son=0;
      }
      if(son){
      	aux=h[son];
         h[son]=h[k];
         h[k]=aux;

         poz[h[son]]=son;
         poz[h[k]]=k;
         k=son;
      }
    } while(son);
}

void CUT(long k){
   poz[h[k]]=0;
	h[k]=h[l];
   poz[h[l]]=l;
//   --l;

   if(k>1 && (h[k] < h[tata(k)]))
     UP(k);
   else DOWN(k);
}

int main(){
	freopen("heapuri.in","r",stdin);
   freopen("heapuri.out","w",stdout);
   scanf("%ld",&q);
   l=0; //lg heap
   for(i=1;i<=q;++i){
   	scanf("%ld",&op);
      if(op==1){
         scanf("%ld",&x);
         ++l; ++nr;
         a[l]=x;
         h[l]=nr;
         poz[nr]=l;
         UP(l);
      }
      else
      if(op==2){
      	scanf("%ld",&x);
       //  a[x]=-1;
         CUT(poz[x]);
      }
      else
      if(op==3) printf("%ld\n",a[h[1]]);
   }

   fclose(stdin); fclose(stdout);
   return 0;
}