Cod sursa(job #679314)

Utilizator lxnchPopescu Ion lxnch Data 13 februarie 2012 01:33:45
Problema Heapuri Scor 20
Compilator c Status done
Runda Arhiva educationala Marime 2.66 kb
#include <stdio.h>
#include <stdlib.h>

#define MAXN 200001
#define DMAXN 1000000000
#define fisin "heapuri.in"
#define fisout "heapuri.out"

int heap[MAXN], poz[MAXN], val[MAXN];
int pozitie=-1, dimensiune=-1;

void afiseaza() {
  unsigned int i;
  printf("Heap: ");
  for (i=0;i<=dimensiune;i++)
    printf("%d ", val[heap[i]]);
  printf("\n");
  printf("Val : ");
  for (i=0;i<4;i++)
    printf("%d ", val[i]);
  printf("\n");
  printf("Pozi: ");
  for (i=0;i<4;i++)
    printf("%d ", poz[i]);
  printf("\n");
}

inline int tata(int poz) { return (poz-1)/2; }
inline int fiu_st(int poz) { return poz*2+1; }
inline int fiu_dr(int poz) { return poz*2+2; }

inline void swap(int *z, int *y)
{
  int temp=*z; *z=*y; *y=temp;
}

void heapUP(int start)
{
  do {
    int fiu = fiu_st(start);
    if ((fiu < dimensiune-1) && (val[heap[fiu]] > val[heap[fiu+1]])) fiu++;
    if (val[heap[start]] > val[heap[fiu]])
      {
	//printf("Swap %d(p %d) cu %d(p %d)\n",val[heap[start]], poz[heap[start]], val[heap[fiu]], poz[heap[fiu]]);
      swap(&poz[heap[start]], &poz[heap[fiu]]);
      swap(&heap[start], &heap[fiu]);
      start=tata(start);
      }
    else
      break;
  } while(start>=0);
}

void heapDOWN(int start)
{
  while (fiu_st(start) <= dimensiune)
    {
      unsigned int fiu = fiu_st(start);
      if ((fiu < dimensiune) && (val[heap[fiu]] > val[heap[fiu+1]])) fiu++;
      if (val[heap[start]] > val[heap[fiu]])
	{
	  swap(&poz[heap[start]], &poz[heap[fiu]]);
	  swap(&heap[start], &heap[fiu]);
	  start=fiu;
	}
      else
	{
	  break;
	}
    }
}

void insereaza(int elem)
{
  dimensiune++; pozitie++;

  val[pozitie] = elem;
  poz[pozitie] = dimensiune;
  heap[dimensiune] = pozitie;

  heapUP(tata(dimensiune)); // urc unde-i e locul
}

void elimina(int p)
{
  int pozHeap = poz[p-1];
  swap(&heap[pozHeap], &heap[dimensiune]);
  swap(&poz[heap[pozHeap]], &poz[heap[dimensiune]]);
  dimensiune--;

  if((pozHeap > 0) && val[heap[pozHeap]] > val[heap[tata(pozHeap)]])
    { // trebuie urcat
      heapUP(tata(pozHeap));
    }
  else
    { // trebuie coborat
      heapDOWN(pozHeap);
    } 
}

int main(int argc, char *argv[])
{
  int op1, op2, n;
  unsigned int i;
  freopen(fisin, "r", stdin);
  freopen(fisout, "w", stdout);

  scanf("%d", &n);
  for(i=0; i<n; i++)
    {
      scanf("%d", &op1);
      switch (op1) {
      case 1: //inserare
	scanf("%d", &op2);
	if (op2 > DMAXN || op2 < 1)
	  exit(1);  // nr natural >0 si <1miliard, ori PA!
	insereaza(op2);
	break;
      case 2: //eliminare
	scanf("%d", &op2);
	if (op2-1 > pozitie || op2 < 1)
	  exit(1);
	elimina(op2);
	break;
      case 3: //afisare min
	printf("%d\n", val[heap[0]]);
	break;
      default:
	exit(1);
	break;
      }
    }
  return 0;
}