Cod sursa(job #1323860)

Utilizator gabrielvGabriel Vanca gabrielv Data 21 ianuarie 2015 16:52:18
Problema Heapuri Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
#include <cstdio>
#include <algorithm>

using namespace std;

#define NMAX 200010
#define V(x) Heap[x].val
#define O(x) Heap[x].ord

int N;
int Ord[NMAX];

struct
{
    int val;
    int ord;
} Heap[NMAX];

inline bool CMP(int a, int b)
{
    return V(a)<V(b);
}

inline int father(int n)
{
    return n>>1;
}

inline int left_son(int n)
{
    return n<<1;
}

inline int right_son(int n)
{
    return (n<<1)+1;
}

inline void Swap(int a, int b)
{
    swap(V(a),V(b));
    swap(O(a),O(b));
    swap(Ord[O(a)],Ord[O(b)]);
}

void Up(int n)
{
    while(n > 1 && CMP(n,father(n)))
    {
        Swap(n,father(n));
        n = father(n);
    }
}

void Down(int n)
{
    int son;
    do
    {
        son = 0;
        if(left_son(n) <= N)
        {
            son = left_son(n);

            if(right_son(n) <= N && CMP(right_son(n),son))
                son = right_son(n);

            if(CMP(n,son))
                son = 0;
        }
        if(son)
            Swap(n,son);
        n = son;
    }while(son);
}

void Insert (int x)
{
    N++;
    V(N)=x;
    O(N)=N;
    Ord[N]=N;
    Up(N);
}

void RemoveAt (int x)
{
    Swap(x,N);
    N--;

    if(x > 1 && CMP(x,father(x)))
        Up(x);
    else
        Down(x);

}

int main()
{
    freopen("heapuri.in","r",stdin);
    freopen("heapuri.out","w",stdout);

    int M,x,op;

    scanf("%d",&M);
    while(M--)
    {
        scanf("%d",&op);

        switch(op)
        {
            case 1:
            {
                scanf("%d",&x);
                Insert(x);
                break;
            }
            case 2:
            {
                scanf("%d",&x);
                RemoveAt(Ord[x]);
                break;
            }
            case 3:
            {
                printf("%d\n",Heap[1]);
                break;
            }
        }
    }

    return 0;
}