Cod sursa(job #2293176)

Utilizator CristyXtremeSimion Cristian CristyXtreme Data 30 noiembrie 2018 17:18:21
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.54 kb
/* Trebuie stabilita o corespondenta intre ordinea cronologica si cea din Heap
   Am folosit vectorii poz si cronologie ca inversii unuia celuilalt, astfel pot schimba cronologiile in functie de pozitie
*/
#include <stdio.h>

using namespace std;

int poz[200001], cronologie[200001];
int numere_inserate = 0;

void interschimba(int &a, int &b) {
    int aux = a;
    a = b;
    b = aux;
}

void sus(int &pos, int *heap) {
    while (pos > 1 && heap[pos] < heap[pos / 2]) {
        interschimba(cronologie[poz[pos]], cronologie[poz[pos / 2]]);   // interschimba pozitiile pe care le indica pozitiile cronologice
        interschimba(poz[pos], poz[pos / 2]);                           // interschimba pozitiile pe care le indica pozitiile din heap
        interschimba(heap[pos], heap[pos / 2]);
        pos = pos / 2;
    }
}

void jos(int pos, int *heap, int dim_heap) {
    while (true) {
        // daca nu are fii inseamna ca e pe pozitia corecta (avand in vedere ca valoarea de unde a venit era mai mica)
        if (pos * 2 > dim_heap)
            return;
        if (pos * 2 == dim_heap) { // are doar un fiu
            if (heap[pos] > heap[pos * 2]) {
                interschimba(cronologie[poz[pos]], cronologie[poz[pos * 2]]);
                interschimba(poz[pos], poz[pos * 2]);
                interschimba(heap[pos], heap[pos * 2]);
                pos *= 2;
            }
            else
                return;
        }
        else { // daca a ajuns pana aici inseamna ca are 2 fii
            int min_fiu_pos = pos * 2; // presupunem ca fiul stang e mai mic
            if (heap[pos * 2] > heap[pos * 2 + 1])
                min_fiu_pos++;  // al doilea fiu este cel cu care trebuie sa schimbam (min_fiu_pos++ echivalent cu min_fiu_pos = pos * 2 + 1)
            if (heap[pos] > heap[min_fiu_pos]) {
                interschimba(cronologie[poz[pos]], cronologie[poz[min_fiu_pos]]);
                interschimba(poz[pos], poz[min_fiu_pos]);
                interschimba(heap[pos], heap[min_fiu_pos]);
                pos = min_fiu_pos;
            }
            else
                return;
        }
    }
}

void insert_heap(int valoare, int *heap, int &dim_heap) {
    // inseram valoarea pe ultima pozitie, apoi urcam in sus pana gasim pozitia corecta
    dim_heap++;
    cronologie[numere_inserate] = dim_heap;
    poz[dim_heap] = numere_inserate;
    heap[dim_heap] = valoare;
    int poz_start = dim_heap;
    sus(poz_start, heap);
}

void delete_heap(int pos, int *heap, int &dim_heap) {
    // interschimbam ultimul element cu cel pe care vrem sa il stergem
    interschimba(heap[pos], heap[dim_heap]);
    interschimba(cronologie[poz[pos]], cronologie[poz[dim_heap]]);
    interschimba(poz[pos], poz[dim_heap]);
    // este sansa ca interschimbarea sa aduca elementul intr-o pozitie ciudata, de aceea trebuie sa il mutam cat de sus putem, apoi jos (o poate lua pe cealalta ramura)
    sus(pos, heap);
    dim_heap--;
    jos(pos, heap, dim_heap);

}

int main() {
	freopen("heapuri.in", "r", stdin);
	freopen("heapuri.out", "w", stdout);
	int n, cod, x, dim_heap = 0;
	scanf("%d", &n);
	int heap[n + 1];
	for (int i = 0; i < n; i++) {
        scanf("%d", &cod);
        if (cod == 3)
            printf ("%d\n", heap[1]);
        else {
            scanf("%d", &x);
            if (cod == 1) {
                numere_inserate++;
                insert_heap(x, heap, dim_heap);
            }
            else
                delete_heap(cronologie[x], heap, dim_heap);
        }
	}
	return 0;
}