Cod sursa(job #603062)

Utilizator vendettaSalajan Razvan vendetta Data 14 iulie 2011 12:58:10
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.22 kb
#include <cstdio>
#include <algorithm>
using namespace std;

int pos[200000], v[200000], h[200000], 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);// fiul din stanga
        int Dfiu=fiu_dreapta(k);//fiul din dreapta
        if (Sfiu <= l){//daca fiul stang exista
            fiu = Sfiu;//alegem fiul stang
            if (Dfiu <= l && v[h[Dfiu]] < v[h[Sfiu]])//daca exista fiul drept si acesta e mai mare ca fiul stang atunci
                fiu = Dfiu;// alegem fiul drept
            if (v[h[fiu]]>=v[h[k]])//daca tatal e mai mare ca fiul ales atunci
                fiu = 0;//ne oprim;
        }
        if ( fiu ) {//daca fiul e mai mare ca si tatal atunci
            swap(pos[h[k]],pos[h[fiu]]);
            swap(h[k],h[fiu]);//ii interschimbam
            k = fiu;// si verificam din nou cu exceptia ca nodul k(cel cu probleme) i`a valoare fiului
        }
    }
}

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

    while ((k > 1) && v[key]<v[h[tata_fiului(k)]]){//cat timp nu suntem pe nivelul 0 si fiul e mai mare ca si tatal atunci
        pos[h[tata_fiului(k)]]=pos[h[k]];
        h[k]=h[tata_fiului(k)];//fiul i`a valoarea tatalui
        k = tata_fiului(k);//verificam urm nivel
        h[k] = key;//punem cheia la locul iei;( fie ca si fiu, fie ca si radacina )
        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;
}