Cod sursa(job #398883)

Utilizator dead_knightTitei Paul Adrian dead_knight Data 19 februarie 2010 16:50:37
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
using namespace std;
#include<cstdio>
#include<fstream>
#include<iostream>
#define MAX 200005
inline int father(int k){
    return k/2;}
inline int left_son(int k){
    return k*2;}
inline int right_son(int k){
    return k*2+1;}

int heap[MAX],poz[MAX],v[MAX],n,N;

void promoveaza(int k)
{
    while((k>1) && (v[heap[father(k)]]>v[heap[k]]))
    {
        swap(heap[father(k)],heap[k]);
        swap(poz[heap[k]],poz[heap[father(k)]]);
        k=father(k);
    }
}

void cerne(int k)
{
    int son;
    do
    {
        son=0;
        if(left_son(k)<=n)
        {
            son=left_son(k);
            if(right_son(k)<=n && v[heap[right_son(k)]]<v[heap[son]])
                son=right_son(k);
            if(v[heap[son]]>=v[heap[k]])
                son=0;
        }
        if(son)
        {
            swap(heap[son],heap[k]);
            swap(poz[heap[son]],poz[heap[k]]);
            k=son;
        }
    }while(son);
}

void add(int valoare)
{
    v[++N]=valoare;
    heap[++n]=N;
    poz[N]=n;
    promoveaza(n);
}

void sterge(int pozitie)
{
    int k=poz[pozitie];
    swap(heap[k],heap[n]);
    swap(poz[heap[k]],poz[heap[n]]);
    n--;
    if(k>1 && v[heap[k]]<v[heap[father(k)]])
        promoveaza(k);
    else
        cerne(k);
}

int main()
{
    freopen("heapuri.in","r",stdin);
    freopen("heapuri.out","w",stdout);
    int i,nrop,op,x;
    scanf("%d", &nrop);
    for(i=1;i<=nrop;i++)
    {
        scanf("%d ", &op);
        if(op==3)
            printf("%d\n", v[heap[1]]);
        else
        {
            scanf("%d", &x);
            if(op==1)
                add(x);
            else
                sterge(x);
        }
    }
}