Cod sursa(job #2025237)

Utilizator rangal3Tudor Anastasiei rangal3 Data 22 septembrie 2017 10:13:35
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.36 kb
#include <fstream>
#define in "heapuri.in"
#define out "heapuri.out"
#define N 200003

using namespace std;

ifstream fin(in);
ofstream fout(out);

int n,p,x;
int A[N],heap[N],pos[N]; /* A pastreaza valorile adaugate in ordine
                            heap[i] = j, elementul de pe pozitia i in heap este al j-lea adaugat,
                            adica elementul cu valoarea A[j]. -> heap[A[i]]= j,pe pozitia i se afla j.

                            pos[i] = j, al i-lea element adaugat se afla pe pozitia j.
                            */
int hn,An;// hn - cate elemente se mai afla in heap, An - cate elemente au fost adaugate pana acum

inline int father(const int &nod)
{
    return nod/2;
}

inline int left_son(const int &nod)
{
    return nod*2;
}

inline int right_son(const int &nod)
{
    return nod*2 + 1;
}

inline int min_heap()
{
    return A[heap[1]];
}

inline void percolate(int poz)
{
    while(poz > 1 && A[heap[father(poz)]] > A[heap[poz]])
    {
        swap(heap[poz],heap[father(poz)]);
        swap(pos[heap[poz]],pos[heap[father(poz)]]);
        poz = father(poz);
    }
}

inline void sift(int poz)
{
    int son;
    do
    {
        son = 0;

        if(left_son(poz) <= hn)
        {
            son = left_son(poz);
            if(right_son(poz) <=hn && A[heap[right_son(poz)]] <A[heap[son]]) son = right_son(poz);

            if(A[heap[son]] >= A[heap[poz]]) son = 0;
        }

        if(son != 0)
        {
            swap(heap[poz],heap[son]);
            swap(pos[heap[poz]],pos[heap[son]]);
            poz = son;
        }

    } while(son != 0);
}

inline void adaugare(const int &x)
{
    A[++An] = x;
    heap[++hn] = An;
    pos[An] = hn;

    percolate(hn);
}

inline void sterge(const int &poz)
{
    heap[poz] = heap[hn];
    pos[heap[hn]] = poz; // heap[hn] - elementul de pe pozitia hn este intrat al x-lea
                         // pos[x] - elementul intrat al x-lea s-a mutat pe pozitia poz.
    sift(poz);
}

int main()
{
    fin>>n;
    while(n--)
    {
        fin>>p;
        if(p<3) fin>>x;
        switch(p)
        {
            case 1: adaugare(x);
            break;
            case 2: sterge(pos[x]);
            break;
            case 3: fout<<min_heap()<<"\n";

        }
    }


    fin.close(); fout.close();
    return 0;
}