Cod sursa(job #259839)

Utilizator mika17Mihai Alex Ionescu mika17 Data 15 februarie 2009 22:33:52
Problema Heapuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define le(K) K << 1
#define ri(K) (K << 1) + 1
#define fa(K) K >> 1
#define MINP 1
#define NEWP ++HSZ
#define MAX_SZ 200001

int H[MAX_SZ],HSZ;
int now,pos[MAX_SZ],ord[MAX_SZ];

void hswap(int x,int y) {
        int aux, sx = ord[x], sy = ord[y];
        aux = ord[x]; ord[x] = ord[y]; ord[y] = aux;
        aux = pos[ sx ]; pos[ sx ] = pos[ sy ]; pos[ sy ] = aux;
        aux = H[x]; H[x] = H[y]; H[y] = aux;
}

int dip(int K) {

        bool fl,fr;
        do {
         fl = fr = false;
         if(le(K) <= HSZ && H[K] > H[le(K)])
          fl = true, hswap(K,le(K));
         if(ri(K) <= HSZ && H[K] > H[ri(K)])
          fr = true, hswap(K,ri(K));
         K = fl ? le(K) : fr ? ri(K) : K;
        }
        while (fl || fr);

        return K;
}

int lift(int K) {

        while(fa(K) && H[K] < H[fa(K)])
         hswap(K,fa(K)), K = fa(K);

        return K;
}

inline int get(int K) {

        return H[K];
}

int del(int K) {       //returneaza valoarea de pe poz K

        int sav = H[K];
        hswap(K,HSZ--);
        dip(K);
        return sav;
}
int set(int K,int v,int x) {  //returneaza pozitia finala pe care s-a inserat

        H[K] = v;

        ord[K] = x, pos[x] = K;

        if(le(K) <= HSZ && H[K] > H[le(K)] || ri(K) <= HSZ &&H[K] > H[ri(K)])
          return dip(K);
         else if(fa(K) && H[K] < H[fa(K)]) return lift(K);

        return K;
}

int main() {

        freopen("heapuri.in","r",stdin);
        freopen("heapuri.out","w",stdout);

        int N;
        
        scanf("%d",&N);

        int op;
        while(N--) {

                scanf("%d",&op);

                int x;
                switch(op) {

                        case 1: scanf("%d",&x);
                                set(NEWP,x,++now);
                                break;

                        case 2: scanf("%d",&x);
                                del(pos[x]);
                                break;

                        case 3: printf("%d\n",get(MINP));
                           }

                   }
           }