Cod sursa(job #1538231)

Utilizator daneel95Holteiu Daniel-Ninel daneel95 Data 28 noiembrie 2015 18:08:26
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.73 kb
#include <fstream>

using namespace std;

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

int heap[200005],poz_heap[200005],poz_vector[200005];
int n,q=0;

void interschimb(int a,int b)
{
    int s=poz_vector[a];
    int t=poz_vector[b];
    int aux;
    aux=heap[b];
    heap[b]=heap[a];
    heap[a]=aux;
    poz_vector[b]=s;
    poz_heap[s]=b;
    poz_vector[a]=t;
    poz_heap[t]=a;
    return;
}
//heap,cate noduri, nod k =>in jos il normalizeaza
void sift(int heap[],int n,int k)
{
    int fiu,fiu_stang,fiu_drept,aux;
    do{
        fiu=0;
        fiu_stang=2*k;
        fiu_drept=2*k+1;
        if(fiu_stang<=n)
        {
            fiu=fiu_stang;
            if(fiu_drept<=n && heap[fiu_drept]<heap[fiu_stang]) fiu=fiu_drept;
            if(heap[fiu]>=heap[k]) fiu=0;
        }
        if(fiu)
        {
            interschimb(k,fiu);
            //aux=heap[k];
            //heap[k]=heap[fiu];
            //heap[fiu]=heap[k];
            k=fiu;
        }
    }while(fiu);
    return;
}

//heap,cate noduri, nod k =>in sus il normalizeaza
void percolate(int heap[],int n,int k)
{
    int cheie=heap[k];
    int tata=k/2;
    while((k>1)&&(cheie<heap[tata]))
    {
        interschimb(k,tata);
        //heap[k]=heap[tata];
        k=tata;
        tata=k/2;
    }
    heap[k]=cheie;
    return;
}

//inserarea unui element in heap
void insert(int heap[],int &n,int cheie)
{
    n++;
    q++;
    poz_heap[q]=n;
    poz_vector[n]=q;
    heap[n]=cheie;
    percolate(heap,n,n);
    return;
}

//stergerea unui element din heap
void stergere(int heap[],int &n,int cheie)
{
    int tata=cheie/2;
    interschimb(cheie,n);
    //heap[cheie]=heap[n];
    n--;
    if((cheie>1)&&(heap[cheie] < heap[tata])) percolate(heap,n,cheie);
        else sift(heap,n,cheie);
    return;
}

int main()
{
    int i,x,operatie,nr_noduri=0,j;
    in>>n;
    for(i=1;i<=n;i++)
    {
        in>>operatie;
        if(operatie==1)
        {
            in>>x;
            insert(heap,nr_noduri,x);
        }

        if(operatie==2)
        {
            in>>x;
            stergere(heap,nr_noduri,poz_heap[x]);
        }

        if(operatie==3)
        {
            out<<heap[1]<<"\n";
        }
        //out<<"Heapul este: "<<"\n";
        //for(j=1;j<=nr_noduri;j++) out<<heap[j]<<" ";
        //out<<"\n";
    }
    in.close();
    out.close();
    return 0;
}




/*#include <fstream>

using namespace std;

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

int n,x,operatie,p=1;
int heap[200005],ordine[200005],pozitie[200005];

//Prin vectorul ordine tin minte ce elemnt a fost inserate al i-lea
//De fiecare data cand fac sift,fa_heap sau inserare (la stergere fac sift/fa_heap) reschimb pozitiile.

//Procedura asta e de pe infoarena si il face heap incepand cu pozitia k (in jos) - sau asa cred :)
void sift(int heap[],int &inaltime,int k)
{
    int fiu,aux;
    do{
        fiu=0;
        if(2*k <= inaltime)
        {
            fiu=2*k;
            if(2*k+1 <= inaltime && heap[2*k+1]<heap[2*k]) fiu=2*k+1;
            if(heap[fiu] >= heap[k]) fiu=0;
        }
        if(fiu){
            pozitie[heap[fiu]]=k;
            pozitie[heap[k]]=fiu;
            aux=heap[k];
            heap[k]=heap[fiu];
            heap[fiu]=aux;
        }
    }while(fiu);
    return;
}

//Si asta e tot de pe infoarena si face vectorul meu heap doar ca opus lui sift(adica in sus) - sau asa cred :)
void fa_heap(int heap[],int &inaltime,int k)
{
    int cheie=heap[k];

    while((k>1) && (cheie<heap[k/2]))
    {
        heap[k]=heap[k/2];
        pozitie[heap[k/2]]=k;
        k=k/2;
    }
    pozitie[cheie]=k;
    heap[k]=cheie;
    return;
}

//Inserare de element in heap
void inserare_heap(int heap[],int &inaltime,int x)
{
    inaltime++;
    heap[inaltime]=x;
    ordine[p]=x;
    p++;
    pozitie[p]=inaltime;
    fa_heap(heap,inaltime,inaltime);
    return;
}

//stergere element din heap
void stergere_heap(int heap[],int &inaltime,int poz)
{
    heap[poz]=heap[inaltime];
    inaltime--;
    if(poz>1 && heap[poz]<heap[poz/2]) fa_heap(heap,inaltime,poz);
        else sift(heap,inaltime,poz);
    return;
}


int main()
{
    int i,inaltime;
    in>>n;
    inaltime=0;
    for(i=1;i<=n;i++)
    {
        in>>operatie;
        if(operatie==1)
        {
            in>>x;
            inserare_heap(heap,inaltime,x);
        }
        if(operatie==2)
        {
            in>>x;
            if(inaltime>0) stergere_heap(heap,inaltime,pozitie[ordine[x]]);
        }
        if(operatie==3)
        {
            out<<heap[1]<<"\n";
        }
    }
    in.close();
    out.close();
    return 0;
}
*/