Cod sursa(job #603082)

Utilizator vendettaSalajan Razvan vendetta Data 14 iulie 2011 13:49:07
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <cstdio>
#include <algorithm>
#define nmax 200000
using namespace std;

int pos[nmax], v[nmax], h[nmax], i, j, n, nr=0, l=0;

inline int tata_fiului(int nod){
    return nod / 2;
}
inline int fiu_stanga(int nod){
    return 2 * nod;
}
inline int fiu_dreapta(int nod){
    return 2 * nod + 1;
}

void sift(int k){
    int fiu=1;
    while (fiu){
        fiu = 0;
        int Sfiu=fiu_stanga(k);
        int Dfiu=fiu_dreapta(k);
        if (Sfiu <= l){
            fiu = Sfiu;
            if (Dfiu <= l && v[h[Dfiu]] < v[h[Sfiu]])
                fiu = Dfiu;
            if (v[h[fiu]]>=v[h[k]])
                fiu = 0;
        }
        if ( fiu ) {
            swap(pos[h[k]],pos[h[fiu]]);
            swap(h[k],h[fiu]);
            k = fiu;
        }
    }
}

void percolate(int k){
    int key=h[k];

    while ((k > 1) && v[key]<v[h[tata_fiului(k)]]){
        pos[h[tata_fiului(k)]]=pos[h[k]];
        h[k]=h[tata_fiului(k)];
        k = tata_fiului(k);
        h[k] = key;
        pos[h[k]]=k;
    }
}

void insert(int k){
    ++nr;++l;
    v[nr]=k;
    h[l]=nr;
    pos[nr]=l;
    percolate(l);
}

void cut(int k){
    pos[h[l]]=k;
    h[k]=h[l];
    k = pos[h[k]];
    --l;
    if( (k>1) && (v[h[k]]<v[h[tata_fiului(k)]]) )
        percolate(k);
    else sift(k);
}
int main(){
    freopen("heapuri.in","r",stdin);
    freopen("heapuri.out","w",stdout);

    scanf("%d\n",&n);
    for (i=1;i<=n;i++){
        int tip, x;
        scanf("%d ",&tip);
        if (tip==3) printf("%d\n",v[h[1]]),scanf("\n");
        if (tip==1) scanf("%d\n",&x),insert(x);
        if (tip==2) scanf("%d\n",&x),cut(pos[x]);
    }

    return 0;
}