Cod sursa(job #2024446)

Utilizator rangal3Tudor Anastasiei rangal3 Data 20 septembrie 2017 18:02:50
Problema Heapuri Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.89 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 heap[N],leg[N],leg2[N]; // leg[i] = j, elementul intrat pe pozitia i se afla pe pozitia j.
                            //leg2[i] = j, elementul de pe pozitia j a intrat pe pozitia i.
int hn,legn; // legn - cate elemente s-au adaugat in leg[]. hn - cate elemente se mai afla in heap.

inline int swap(int &a,int &b)
{
    int aux = a;
    a = b;
    b = aux;
}

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

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

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

inline void percolate(const int &hn)
{
    int son;
    int poz = hn; // pozitia actuala a lui heap[hn]
    while(poz > 1)
    {
        if(heap[father(poz)] >  heap[poz])
        {
            swap(heap[father(poz)], heap[poz]);
            /* leg2[i] = j,
            leg2[i2] = j2;
            swap... ->
            leg2[i] = j2;
            leg2[i2] = j;

            -> leg[j2] = i,
            leg[i2] = j;
            */

            int i = father(poz);
            int i2 = poz;
            int j = leg2[i];
            int j2 = leg2[i2];

            //swap(leg2[father(poz)], leg2[poz]);
            leg2[i] = j2;
            leg2[i2] = j;

            leg[j2] = i;
            leg[j] = i2;

            poz = father(poz);
        }
        else poz = 0;
    }
}

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

        if(left_son(nod) <= hn) // daca nu este frunza
        {
            son = left_son(nod);

            if(right_son(nod) <= hn && heap[right_son(nod)] < heap[son])
                son = right_son(nod);
            if(heap[son] >= heap[nod]) son = 0;
        }

        if(son != 0)
        {
            swap(heap[nod],heap[son]);

            int i = father(nod);
            int i2 = nod;
            int j = leg2[i];
            int j2 = leg2[i2];

            //swap(leg2[father(poz)], leg2[poz]);
            leg2[i] = j2;
            leg2[i2] = j;

            leg[j2] = i;
            leg[j] = i2;
        }

    } while(son != 0);
}

inline void insereaza(const int &x)
{
    heap[++hn] = x;
    leg[++legn] = hn;
    leg2[hn] = legn;
    percolate(hn);
}

void sterge(int poz)
{
    heap[poz] = heap[hn];
    leg[leg2[hn]] = poz;

    leg2[poz] = leg2[hn];
    --hn;
    sift(poz);
}

int main()
{
    fin>>n;
    while(n--)
    {
        fin>>p;
        switch(p)
        {
            case 1: fin>>x;
            insereaza(x);
            break;
            case 2: fin>>x;
            sterge(leg[x]);
            break;
            default: fout<<heap[1]<<"\n";
            break;
        }
    }


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