Cod sursa(job #785747)

Utilizator vendettaSalajan Razvan vendetta Data 9 septembrie 2012 19:45:58
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.32 kb
#include <iostream>
#include <fstream>

using namespace std;

ifstream f("heapuri.in");
ofstream g("heapuri.out");

#define nmax 200005


//Poz[] poztia in heap a unui elemnt din vector
//Heap[] pozitia in vector a unui elemnt din Heap

int n, V[nmax], Heap[nmax], Poz[nmax], cnt_H;

void citeste(){

	f >> n;//numarul de operatii

}

void in_sus(int Nod){

    //ma tot dus in sus pe arbore pana ii gasesc pozitia;

    if (Nod == 1) return;
    if ( V[ Heap[Nod] ] < V[ Heap[Nod/2] ] ){//asta inseamna ca Nodul e mai "bun" decat tatal sau asa ca il schimb
        swap(Poz[ Heap[Nod] ], Poz[ Heap[Nod/2] ]);//schimb si Poz[]
        swap(Heap[Nod], Heap[Nod/2]);//schimb elementele din Heap[]
        in_sus(Nod/2);
    }

}

void in_jos(int Nod){

    //ma duc in jos; aleg fiul minim; daca exista un fiu minim , daca nu estia ma opresc

    int Fiu_min = Nod;
    int St = Nod*2; //fiul din stanga
    int Dr = Nod*2+1;//fiul din dreapta

    if ( St <= cnt_H && V[ Heap[St] ] < V[ Heap[Fiu_min] ] ) Fiu_min = St;
    if ( Dr <= cnt_H && V[ Heap[Dr] ] < V[ Heap[Fiu_min] ] ) Fiu_min = Dr;

    if (Fiu_min == Nod) return; // cazul cand heap-ul e corect

    swap( Poz[ Heap[Nod] ], Poz[ Heap[Fiu_min] ] );
    swap( Heap[Nod], Heap[Fiu_min] );

    in_jos(Fiu_min);

}

void adauga(int X){

    ++cnt_H;//imi zice cate elemente contine heap-ul
    ++V[0];//imi zice nr de elemente adaugate pana la acest pas
    V[ V[0] ] = X;
    Poz[ V[0] ] = cnt_H;//Poz[ X ] = Y ; Poz[] imi zice pozitia,elementului al X-lea din vectorul V[], in Heap;
    Heap[cnt_H] = V[0];// asta inseamna ca pe pozitia cnt_H din vectorul Heap adaug al V[0]-lea element
    in_sus(cnt_H);

}

void sterge(int X){

    //trebuie sa sterg al X-lea element introdus;
    // al X-lea element introdus ii V[X];
    //stergerea o fac punand ultimul element adaugat in locul ementului pe care vreau sa il sterg

    int poz_H = Poz[X];// pozitia in HEAp al elementului  cu ordinea X in vectorul V[];

    //pozitia in Heap a ultimului element va fi pozitia in Heap a elemntului pe care il sterg
    Poz[ Heap[cnt_H] ] = Poz[ Heap[ poz_H ] ];

    //pozitia in V[] a elementului pe carfe vreau sa il sterg(pt ca pratic eu il sterg pe ultimul din heap => pe ala care voriam sa il sterg initial
                                                              //o sa ia valoarea ultimului element din heap)
    Heap[ poz_H ] = Heap[ cnt_H ];

    --cnt_H;//sterg ultimul element din heap
    //si acum "corectez" heap-ul
    int Nod = Poz[ Heap[ poz_H ] ];// Nod = pozitia in Heap a elementului pus in locul elementului sters

    //sunt 3 variante : heap-u e stricat in sus , in jos sau deloc
    if (Nod > 1 && V[ Heap[Nod] ] < V[ Heap[Nod/2] ]){
        in_sus(Nod);
    }else in_jos(Nod);

}

void rezolva(){

    //1 : insereaza elemntul X in multime;
    //2 : sterge al - X -lea element introdus (in ordine cronlogica, evident)
    //3 : afisarea minimul din multime

    for(int i=1; i<=n; ++i){
        int tip, X;
        f >> tip;
        if (tip == 1){
            f >> X;
            adauga(X);
        }else if (tip == 2){
            f >> X;
            sterge(X);
        }else{
            g << V[ Heap[1] ] << "\n";
        }
    }

}

int main(){

    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;

}