Cod sursa(job #1089622)

Utilizator gabrielvGabriel Vanca gabrielv Data 21 ianuarie 2014 20:09:02
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include<cstdio>

using namespace std;

#define NMAX 2000005

int H[NMAX],Idx[NMAX],Ord[NMAX];
int n,k;

inline int father(int nod) {
    return nod>>1;
}
inline int left_son(int nod) {
    return nod<<1;
}
inline int right_son(int nod) {
    return (nod<<1)+1;
}

void swap(int i, int j)
{
    int aux;
    aux=H[i];
    H[i]=H[j];
    H[j]=aux;

    aux=Idx[Ord[i]];
    Idx[Ord[i]]=Idx[Ord[j]];
    Idx[Ord[j]]=aux;

    aux=Ord[i];
    Ord[i]=Ord[j];
    Ord[j]=aux;
}

void percolate(int i)
{
    while(i>1 && H[i]<H[father(i)])
    {
        swap(i,father(i));
        i=father(i);
    }
}
void sift(int N, int i)
{
    int son;
    do
    {
        son=0;
        if(left_son(i)<=N)
        {
            son=left_son(i);
            if(right_son(i)<=N && H[son]>H[right_son(i)])
                son=right_son(i);
            if(H[son]>H[i])
                son=0;
        }
        if(son)
            swap(i,son);
        i=son;
    }while(son);
}

void insert(int x)
{
    n++;
    k++;
    H[n]=x;   // retinem valorile intr-un min-heap
    Idx[k]=n; // Idx[i] = pozitia in heap elementului introdus al i-lea
    Ord[n]=k; // Ord[i] = numarul de ordine al elementului din heap de pe pozitia i
    percolate(n);
}

void cut(int x)
{
    int i=Idx[x];
    swap(i,n);
    n--;
    if(i>1 && H[i]<H[father(i)])
        percolate(i);
    else
        sift(n,i);
}

int main()
{
    freopen("heapuri.in","r",stdin);
    freopen("heapuri.out","w",stdout);
    int op,x,m;
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d",&op);
        if(op==3)
            printf("%d\n",H[1]);
        else
        {
            scanf("%d",&x);
            if(op==1)
                insert(x);
            else
                cut(x);
        }
    }
    return 0;
}