Cod sursa(job #1611071)

Utilizator DanyBvGeorge-Daniel Gagiu DanyBv Data 23 februarie 2016 22:22:41
Problema Heapuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.72 kb
#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

int H[200001], a[200001], pos[200001], o, x, N, n;

int tata(int k)
{
    return k/2;
}

int stang(int k)
{
    return 2*k;
}

int drept(int k)
{
    return 2*k+1;
}

void percolate(int k)
{
    int aux = H[k];
    while(k > 1 && H[k] < H[tata(k)])
    {
        H[k] = H[tata(k)];
        k = tata(k);
    }
    H[k] = aux;
    pos[aux] = k;
}

void sift(int k)
{
    int fiu;
    do
    {
        fiu = 0;
        if(stang(k) <= N)
        {
            fiu = stang(k);
            if(drept(k) <= N && H[drept(k)] < H[stang(k)])
                fiu = drept(k);
            if(H[fiu] >= H[k])
                fiu = 0;
        }
        if (fiu)
        {
            int aux = H[k];
            H[k] = H[fiu];
            H[fiu] = aux;
            pos[fiu] = k;
            k = fiu;
        }
    }
    while(fiu);
}

void minim()
{
    printf("%d\n", H[1]);
}

void insereaza()
{
    a[++N] = x;
    pos[x] = N;
    H[N] = x;
    percolate(N);
}

void sterge()
{
    x = pos[a[x]];
    H[x] = H[N];
    N--;

    if(x > 1 && H[x] < H[tata(x)])
        percolate(x);
    else
        sift(x);
}

int main()
{
    freopen("heapuri.in", "r", stdin);
    freopen("heapuri.out", "w", stdout);
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        scanf("%d", &o);
        if(o < 3) scanf("%d", &x);
        switch(o)
        {
        case 1:
            insereaza();
            break;
        case 2:
            sterge();
            break;
        case 3:
            minim();
            break;
        default:
            break;
        }
    }
    return 0;
}