Cod sursa(job #1213479)

Utilizator DinaAndreiDina Andrei DinaAndrei Data 28 iulie 2014 12:00:20
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.11 kb
#include <cstdio>

using namespace std;

FILE *fin = fopen("heapuri.in","r");
FILE *fout = fopen("heapuri.out","w");

int f,poz,c,p,n,x,y,k;
int v[200005];  // 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[200005];
//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[200005]; // a[i] = al i-lea element adaugat
inline void swi (int &a, int &b){
    int aux;
    aux=a, a=b, b=aux;
}


int main()
{

    fscanf(fin,"%d",&n);
    for(f=1; f<=n; f++){
        //fin>>x;               //citirea pana dupa primul if
        fscanf(fin,"%d",&x);
        if((x==1) || (x==2))
            fscanf(fin,"%d",&y);
            //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>>1);
            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>>=1;
                }else
                    break;
            }
            continue;
        }

        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>>1);
            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>>=1;
                } else
                    break;
            }
            // elementul de sters a ajuns in radacina, acum sterg radacina
            v[1] = v[poz--];
            pl[v[1]] = 1;
            p = 1;
            c = (p<<1);
            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 = (p<<1);
                } else
                    break;
            }
            continue;
        }
        if(x==3)      // afisarea celui mai mare element
            fprintf(fout,"%d\n",a[ v[1] ]);
    }
    return 0;
}