Cod sursa(job #734777)

Utilizator a08iAndrei Ionescu a08i Data 14 aprilie 2012 20:57:07
Problema Heapuri Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.62 kb
#include<iostream>
#include<vector>
#include<cstdio>

using namespace std;


class MinHeap
{
  int *ptr_head;
  int *ptr_last;
  int *nr;
  int nr_last;
  int *loc;
  int capacity;

  public:
  MinHeap(int n)
  {
    ptr_head = new int[n];
    nr = new int[n];
    nr_last = 0;
    loc = new int[n];
    ptr_last = ptr_head;
    capacity = n;
  }

  ~MinHeap()
  {
    delete[] ptr_head;
  }

  void siftup(int *ptr_inserted)
  {
    int position = ptr_inserted - ptr_head +1;
    int parent_pos = max(1, position / 2);
    int * parent = ptr_head + parent_pos -1;

    if(*ptr_inserted < *parent)
    {
      swap(*ptr_inserted, *parent);
      loc[*parent] = parent - ptr_head;
      loc[*ptr_inserted] = ptr_inserted - ptr_head;
      siftup(parent);
    }
  }

  void siftdown(int *ptr_inserted)
  {
    int position = ptr_inserted - ptr_head + 1;
    int left_child = 2 * position;
    int right_child = 2 * position +1;

    int * lft = ptr_head + left_child -1;
    int * rgt = ptr_head + right_child -1;


    // need to make sure not to pass the last element in our heap
    if(lft < ptr_last && (rgt >= ptr_last || (rgt < ptr_last && *rgt > *lft)))
    {
      if(*ptr_inserted > *lft)
      {
        swap(*ptr_inserted, *lft);
        loc[*lft] = lft - ptr_head;
        loc[*ptr_inserted] = ptr_inserted - ptr_head;
        siftdown(lft);
      }
    }
    else if(rgt < ptr_last && *lft > *rgt)
    {
      if(*ptr_inserted > *rgt)
      {
        swap(*ptr_inserted, *rgt);
        loc[*rgt] = rgt - ptr_head;
        loc[*ptr_inserted] = ptr_inserted - ptr_head;
        siftdown(rgt);
      }
    }

  }

  void insert(int n)
  {
    if(ptr_last - ptr_head < capacity)
    {
      *ptr_last = n;
      loc[n] = ptr_last - ptr_head;
      siftup(ptr_last);
      ptr_last++;

      nr[nr_last] = n;
      nr_last++;

    }
    else
    {
      cout << "heap full"<<endl;
    }
  }

  int showmin()
  {
    return *ptr_head;
  }

  void remove(int nth)
  {
    int what = nr[nth-1];

    int where = loc[what];
    loc[what] = 0;
    swap(*(ptr_last-1), *(ptr_head+where));
    loc[*(ptr_head+where)] = where;
    ptr_last--;
    siftdown((ptr_head+where));
  }

};



int main()
{

  freopen("heapuri.in", "r", stdin);
  freopen("heapuri.out", "w", stdout);

  int N, Type, X;
  scanf("%d", &N);

  MinHeap myheap(1000000);

  for(int i=0; i<N; i++)
  {
    scanf("%d", &Type);

    if(Type != 3)
    {
      scanf("%d", &X);
    }

    switch(Type)
    {
      case 1:
        myheap.insert(X);
        break;
      case 2:
        myheap.remove(X);
        break;
      case 3:
        cout << myheap.showmin() << endl;
        break;
    }

  }

  return 0;
}