Cod sursa(job #1577066)

Utilizator bullseYeIacob Sergiu bullseYe Data 23 ianuarie 2016 11:04:09
Problema Heapuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.6 kb
//problema heapuri infoarena
#include <cstdio>
#define NMAX 200010
using namespace std;

int n, H[NMAX];
int timeline[NMAX];//timeline[i]=pozitia pe care se afla al i-lea nod inserat in ordine cronologica
int ordine[NMAX];

int inserare (int[], int&, int);//insereaza nodul in heap
void sterge (int[], int&, int);//sterge nodul de pe pozitia data din heap
void combinare(int[], int, int);


int main()
{
    FILE*fin=fopen ("heapuri.in", "r");
    FILE*fout=fopen ("heapuri.out", "w");
    int i, nrop, a, b;
    fscanf(fin, "%d", &nrop);
    for (i=1; i<=nrop; ++i)
    {
        fscanf(fin, "%d", &a);
        if (a!=3) fscanf(fin, "%d", &b);
        if (a==1)
        {
            timeline[i]=inserare (H, n, b);
            ordine[timeline[i]]=i;
        }
            else
            if (a==2)
                sterge (H, n, timeline[b]);
                else
                fprintf(fout, "%d\n", H[1]);
    }
    fclose(fout);
    return 0;
}

int inserare (int H[NMAX], int &n, int x)//functia returneaza pozitia pe care am introdus nodul x
{
    //il pun mai intai la sfarsit
    int tata, fiu;
    fiu=++n; tata=fiu/2;
    while (tata && H[tata]>x)
    {
        H[fiu]=H[tata];
        fiu=tata;
        tata/=2;
    }
    //la sfarsit, introduc nodul x pe pozitia tata
    H[fiu]=x;
    return fiu;
}

void sterge (int H[NMAX], int &n, int tata)
{
    //ma duc in jos pana scap de nodul de pe pozitia poz
    int fiu, x;
    fiu=tata/2;
    H[tata]=H[n];
    timeline[ordine[n]]=tata;
    --n;

    if (tata/2 && H[tata]<H[tata/2])//ma duc in sus
    {
        fiu=tata;
        tata/=2; x=H[fiu];
        while (tata && H[tata]>x)
        {
            timeline[ordine[tata]]=fiu;
            H[fiu]=H[tata];
            fiu=tata;
            tata/=2;
            //se schimba si timeline + ordine
        }
        H[fiu]=x;
        timeline[ordine[n+1]]=fiu;
    }
        else//ma duc in jos H[tata]>H[tata/2]
            combinare (H, n, tata);
    return;
}

void combinare(int H[NMAX], int n, int i)
// se combina nodul H[i] cu Heapurile cu radacinile 2i si 2i+1, obtinand un nou heap cu radacina H[i]
{
int x=H[i], tata, fiu;
tata=i; fiu=2*i;
while (fiu<=n)
    {
        if (fiu+1<=n && H[fiu+1]<H[fiu]) fiu++;
        // fiu indica cel mai mic dintre fii
        if (H[fiu]<x)
            {
                timeline[ordine[tata]]=fiu;
                H[tata]=H[fiu];
                tata=fiu;
                fiu=tata*2;
            }
            else break;//am gasit locul potrivit pentru x
    }
H[tata]=x;
timeline[ordine[i]]=tata;
}