Cod sursa(job #1213470)

Utilizator DinaAndreiDina Andrei DinaAndrei Data 28 iulie 2014 11:45:05
Problema Heapuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.95 kb
#include <fstream>

using namespace std;

ifstream fin ("heapuri.in");
ofstream fout ("heapuri.out");

int f,poz,c,p,n,x,y,k;
int v[210000];  // v[i], e un indice din a
// de exemplu daca pe pozitiile 1, 2, 3 in a sunt 10 4 8
//v[1] = 2 (adica reprezinta valoarea 4, care e minima)
//fii lui 1, adica v[2] si v[3] sunt indicii celorlalte 2 valori
// adica v[2] = 1 (reprezentand valoarea 10) si v[3] = 3 (8)
int pl[210000];
//pl[i] = pozitia in heap a elementului al-i-lea din a
//pl[1] = 2 (pentru ca elementul 1 din a adica 10 e pe pozitia 2 in heap)
//iar cand se cere stergerea lui se da i(1), pozitia sa din a,
//dar trebuie aflata 2(pl[1]), adica pozitia sa din heap

int a[210000]; // a[i] = al i-lea element adaugat
void swi (int &a, int &b){
    int aux;
    aux=a;
    a=b;
    b=aux;
}


int main()
{
    fin>>n;
    for(f=1; f<=n; f++){
        fin>>x;               //citirea pana dupa primul if
        if((x==1) || (x==2))
            fin>>y;



        if(x==1){     // adaugarea unui element
            //pl[++k]=y;
            k++; // k creste dar cand adaug
            poz++;
            pl[k] = poz;  // pl[i] = pe pe cozitie in heap este elementul intrat al i-lea in multime
            a[k] = y;  // a este vectorul cu numerele bagate in heap
            v[poz]=k;

            c=poz;
            p=poz/2;
            while (p>0) {
                if(a[v[c]]<a[v[p]]){
                    swi(v[p],v[c]);
                    pl[ v[p] ] = p;
                    pl[ v[c] ] = c;
                    c=p;
                    p=p/2;
                }else
                    break;
            }
        }

        if (x==2){       // stergerea unui element... nu e un timp extraordinar, dar merge -> n*log2(n)
            // sterg elementul intrat al y-lea in heap (a carui valoare e a[y])
            // aflu pozitia lui in heap (pl[y])
            // a[y] = -1;
            a[y] = -1;
            c = pl[y];
            p = c/2;
            while (p>=1) {
                if (a[v[c]] < a[v[p]]) {
                    swi(v[p],v[c]);
                    pl[ v[p] ] = p;
                    pl[ v[c] ] = c;
                    c = p;
                    p = p/2;
                } else
                    break;
            }
            // elementul de sters a ajuns in radacina, acum sterg radacina
            v[1] = v[poz--];
            pl[v[1]] = 1;
            p = 1;
            c = 2*p;
            while (c<=poz) {
                if (c+1 <= poz && a[v[c+1]] < a[v[c]] )
                    c++;
                if (a[ v[c] ] < a[ v[p] ]) {
                    swi(v[p],v[c]);
                    pl[ v[p] ] = p;
                    pl[ v[c] ] = c;
                    p = c;
                    c = 2*p;
                } else
                    break;
            }
        }
        if(x==3)      // afisarea celui mai mare element
            fout<<a[v[1]]<<endl;
    }
    return 0;
}