Cod sursa(job #1978283)

Utilizator MaligMamaliga cu smantana Malig Data 7 mai 2017 12:32:16
Problema Heapuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.14 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>

using namespace std;
ifstream in("heapuri.in");
ofstream out("heapuri.out");

#define pb push_back
#define ll long long
const int NMax = 2e5 + 5;
const int inf = 1e9 + 5;

// ternary heap

int N,M,nrInsert;
int idx[NMax];
// idx[i] = indexul in heap al nodului inserat al i-lea in ordine cronologica

struct elem {
    int val,ord;
    elem (int _val = 0,int _ord = 0) {
        val = _val;
        ord = _ord;
    }
}heap[NMax];
// heap[i].val = valoarea nodului de pe pozitia i
// heap[i].ord = pozitia nodului i in ordinea cronologica de inserare

void sift(int node);
// sift(node) coboara nodul de pe pozitia node pana la pozitia corespunzatoare
void percolate(int node);
// percolate(node) urca nodul de pe pozitia node pana la pozitia corespunzatoare
void ins(int val);
// ins(val) insereaza un nou element de valoare val in pozitia N+1
// si il urca pana la pozitia corespunzatoare
void rem(int ord);
// rem(ord) scoate al ord-ulea element inserat in heap,
// schimband acest nod cu ultimul si mutand noul nod pana in pozitia corespunzatoare
void swap_heap(elem& a,elem& b);
// schimba continutul din a si b, avand grija sa schimbe si
// elementele corespunzatoare din vectorul idx

int main()
{
    in>>M;

    N = -1;
    nrInsert = 0;
    while (M--) {
        int tip;
        in>>tip;

        switch (tip) {
        case 1: {
            int val;
            in>>val;

            ins(val);

            break;
        }
        case 2: {
            int ord;
            in>>ord;

            rem(ord);

            break;
        }
        case 3: {
            out<<heap[0].val<<'\n';
            break;
        }
        }
    }

    in.close();out.close();
    return 0;
}

void sift(int node) {

    int son = 0;
    do {
        son = 0;
        int fs = node*3 + 1,
            ss = node*3 + 2,
            ts = node*3 + 3;
        if (fs <= N) {
            son = fs;
            if (ss <= N) {
                if (heap[ss].val < heap[son].val) {
                    son = ss;
                }

                if (ts <= N && heap[ts].val < heap[son].val) {
                    son = ts;
                }
            }
        }

        if (son && heap[son].val < heap[node].val) {
            swap_heap(heap[son],heap[node]);
            node = son;
        }
        else {
            son = 0;
        }
    }
    while (son);
}

void percolate(int node) {

    int dad = (node-1) / 3;
    while (node != 1 && heap[dad].val > heap[node].val) {
        swap_heap(heap[node],heap[dad]);
        node = dad;

        dad = (node-1) / 3;
    }
}

void ins(int val) {

    heap[++N] = elem(val,++nrInsert);
    idx[nrInsert] = N;
    percolate(N);
}

void rem(int ord) {

    int pos = idx[ord];
    swap_heap(heap[pos],heap[N]);
    --N;

    int dad = (pos-1) / 3;
    if (heap[dad].val > heap[pos].val) {
        percolate(pos);
    }
    else {
        sift(pos);
    }
}

void swap_heap(elem& a,elem& b) {
    swap(idx[a.ord],idx[b.ord]);
    swap(a,b);
}