Cod sursa(job #2080832)

Utilizator Teodor.mTeodor Marchitan Teodor.m Data 3 decembrie 2017 16:03:19
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.8 kb
#include <bits/stdc++.h>

using namespace std;
void Boost()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    freopen("heapuri.in", "r", stdin);
    freopen("heapuri.out", "w", stdout);
}

const int Nmax = 2e5 + 10;

pair<int, int > Heap[Nmax]; /// elemntul, al catelea a intrat in heap
int lungime_heap, idx; /// idx contorizeaza elementele intrate in heap
bool removed[Nmax]; /// spune daca elementul removed[i] trebuie sau nu sters

void upHeap(int poz) /// poz este pozitia elementului cu pricina in vectorul Heap
{
    while(poz > 1 && Heap[poz].first < Heap[poz / 2].first) { /// cat timp valoarea tatalui este mai mare
        swap(Heap[poz], Heap[poz / 2]); /// le interschimb si urc mai sus
        poz = poz / 2;
    }
    ///se incheie cand am ajuns pe o pozitie pt. care fiul are valoare mai mare decat tatal
}

void downHeap(int poz)
{
    int fiu;
    while(2 * poz <= lungime_heap) { /// cat timp exista fiul din stanga
        if(2 * poz + 1 > lungime_heap) /// daca fiul drept nu este inseama ca singurul fiu este cel stang
            fiu = 2 * poz;
        else { /// daca exista si fiul stang si fiul drept
            if(Heap[2 * poz].first <= Heap[2 * poz + 1].first) /// il aleg pe cel mai mic dintre cei doi
                fiu = 2 * poz;
            else
                fiu = 2 * poz + 1;
        }

        if(Heap[fiu].first < Heap[poz].first) { /// verific daca fiul cel mai mic este cumva mai mic si decat tata
            swap(Heap[fiu], Heap[poz]); /// atunci ii interschimb
            poz = fiu;
        }
        else /// inseamna ca tatal este mai mic decat amandoi fii si este bine
            break;
    }
}


void cleanUp()
{
    while(removed[Heap[1].second]) { /// apelez la stergerea propriu zisa cat timp removed[Heap[1].second] == true
        swap(Heap[1], Heap[lungime_heap]);
        Heap[lungime_heap] = make_pair(0, 0);
        lungime_heap--;
        downHeap(1);
    }
}

int main()
{
    Boost();
    int n;
    cin >> n;

    for(int i = 1; i <= n; ++i) {
        int x, cod;
        cin >> cod;
        if(cod < 3) cin >> x;

        if(cod == 1) {
            Heap[++lungime_heap] = make_pair(x, ++idx); /// adaug perechea (x, idx)in heap
            removed[idx] = false;
            upHeap(lungime_heap); /// si trebuie sa refac heapu-ul
            continue;
        }

        if(cod == 2) {
            removed[x] = true; /// inseamna ca in momentul in care elementul intrat al x-lea in heap va fi cel mai mic si removed[x] indica true
            cleanUp(); /// acesta va fi sters
            continue;
        }

        if(cod == 3) { /// primul element din heap va fi cel mai mic intotdeauna
            cout << Heap[1].first << '\n';
            continue;
        }
    }
    return 0;
}