Cod sursa(job #257034)

Utilizator Sorin_IonutBYSorynyos Sorin_Ionut Data 12 februarie 2009 18:33:39
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.19 kb
#include<stdio.h>

#define IN "heapuri.in"
#define OUT "heapuri.out"
#define nmax (200*1000+1)

FILE *fin=fopen(IN,"r");
FILE *fout=fopen(OUT,"w");

int i[nmax]; //i[j]-retine valoarea celui de-al j-lea element intrat in heap
int p[nmax]; //p[j]-retine pozitia din hip a elementului elementului  i[j]
int h[nmax]; //min-heap-ul (va retine pozitia din i[] ;))
int n; //numarul de elemente din heap
int o; //numarul de operatii

void add(int x, int n);
void comb(int x, int n);
void del(int x, int n);

int main()
{
 int t,x;

 fscanf(fin,"%d\n",&o); //citim numarul de operatii pe care le vom face ;))
 
 while(o--) //cat timp avem de facut operatii
 {
  fscanf(fin,"%d",&t); //citim tipul operatiei ;))
  
  if(t==1) //avem de inserat un element in heap
  {
   fscanf(fin,"%d",&x);
   i[++i[0]]=x; //salvam ca am intrat pe x :P
   add(i[0],++n); //adaugam elementul i[i[0]] in heap
  }
  else
   if(t==2) //trebuie sa stergem un element din heap ;))
   {
	fscanf(fin,"%d",&x); //numarul de ordine din intrari al elementului ce trebuie sters ;))
    del(p[x],--n); //stergem al x-lea element intrat din heap
   }
   else
    if(t==3)
     fprintf(fout,"%d\n",i[h[1]]); //afisem cea mai mica valoare din heap
 }

 fclose(fin);
 fclose(fout);
 
return 0;
}

void add(int x, int n)
{
 int f=n,t=f/2; //fiul si tatal
 
 while(t&&i[h[t]]>i[x]) //cat timp tatal e mai mare
 {
  h[f]=h[t];
  p[h[f]]=f; //coboram tatal peste fiu :>
  f=t;
  t=f/2; //refacem perechea de tata si fiu
 }
 h[f]=x;
 p[h[f]]=f; //salvam elementul in heap
}

void comb(int x, int n)
{
 int y=h[x]; //salvam pozitia din v a elementului din heap ce trebuie repozitionat
 int t=x,f=2*t; //tatal si fiul
 
 while(f<=n)
 {
  if(f<n&&i[h[f+1]]<i[h[f]])
   f++; //e mai mic al doilea fiu
  if(i[h[f]]<i[y])
  {
   h[t]=h[f];
   p[h[t]]=t; //urcam copilul peste tata
   t=f;
   f=2*t; //refacem tatal si fiu
  }
  else
   f=n+1; //i-am gasit pozitia...oprim cautarea :P
 }
 h[t]=y;
 p[h[t]]=t; //pun la pozitia corecta
}
	
void del(int x, int n)
{
 h[x]=h[n+1]; //copiem ultimul element peste cel pe care il stergem
 p[h[x]]=x; //salvam noua pozitie
 comb(x,n); //refacem heapul
}