Cod sursa(job #2447207)

Utilizator Coroian_DavidCoroian David Coroian_David Data 12 august 2019 13:57:46
Problema Heapuri Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.17 kb
#include <cstdio>

using namespace std;

FILE *f, *g;

int crChar = 262144;

const int buffSize = 262144;

char buff[262150];

bool isDigit(char c)
{
    if(c >= '0' && c <= '9')
        return 1;

    return 0;
}

void refillBuff()
{
    crChar = 0;

    fread(buff, 1, buffSize, f);
}

char getCr()
{
    if(crChar == buffSize)
        refillBuff();

    return buff[crChar ++];
}

int getNr()
{
    char c = getCr();
    int nr = 0, sign = 1;

    while(isDigit(c) == 0 && c != '-')
        c = getCr();

    while(c == '-')
    {
        sign = -1;

        c = getCr();
    }

    while(isDigit(c) == 1)
    {
        nr = nr * 10 + c - '0';

        c = getCr();
    }

    return nr * sign;
}

///Nodul pe care se afla al x-lea nr in ordinea citirii
int poz[200001];

///h[i] = nr de ordine al elementului de pe pozitia i in heap
int h[200001];

///Numarul noduri
int noduri;

///Vectorul
int v[200001];

///Numarul de numere citie
int n;

///Numarul de operatii
int q;

inline void swapp(int &a, int &b)
{
    int aux;

    aux = a;
    a = b;
    b = aux;
}

inline void schimba(int a, int b)
{
    swapp(poz[h[a]], poz[h[b]]);
    swapp(h[a], h[b]);
}

bool cmp(int a, int b)
{
    if(v[h[a]] < v[h[b]])
        return 1;

    return 0;
}

void upHeap(int poz)
{
    while(poz > 1)
    {
        if(cmp(poz, poz / 2) == 1)
            schimba(poz, poz / 2);

        else
        {
            poz = 1;

            break;
        }

        poz /= 2;
    }
}

void downHeap(int poz)
{
    ///Fiu - poz fiu min
    int fiu;

    while(poz * 2 <= noduri)
    {
        fiu = poz;

        if(poz * 2 <= noduri)
        {
            if(cmp(poz * 2, fiu) == 1)
                fiu = poz * 2;
        }

        if(poz * 2 + 1 <= noduri)
        {
            if(cmp(poz * 2 + 1, fiu) == 1)
                fiu = poz * 2 + 1;
        }

        if(poz != fiu)
        {
            schimba(poz, fiu);

            poz = fiu;
        }

        else
        {
            poz = noduri;

            break;
        }
    }
}

void dilit(int poz)
{
    schimba(poz, noduri);

    noduri --;

    downHeap(poz);
}

void readFile()
{
    f = fopen("heapuri.in", "r");
    g = fopen("heapuri.out", "w");

    q = getNr();

    int i;
    int op, x;
    for(i = 1; i <= q; i ++)
    {
        op = getNr();

        if(op == 3)
            fprintf(g, "%d\n", v[h[1]]);

        else
        {
            x = getNr();

            if(op == 1)
            {
                noduri ++;
                n ++;

                ///Adaugam in vector
                v[n] = x;

                ///Adaugam la heap pozitia in vector
                h[noduri] = n;

                ///poz[k] = Nodul corespunzator in heap pentru v[k]
                poz[n] = noduri;

                ///Refacem heapul
                upHeap(noduri);
            }

            else if(op == 2)
            {
                ///Schimbam nodul de pe pozitia x cu pozitia n
                dilit(poz[x]);
            }
        }

//        printf("    %d\n", v[h[1]]);
//        printf("  %d %d\n", v[h[2]], v[h[3]]);
//        printf("%d %d   %d %d\n", v[h[4]], v[h[5]], v[h[6]], v[h[7]]);


    }

    fclose(f);
    fclose(g);
}

int main()
{
    readFile();

    return 0;
}