Cod sursa(job #2622797)

Utilizator danutbodbodnariuc danut danutbod Data 1 iunie 2020 21:03:48
Problema Heapuri Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.71 kb
//5
////----------------------------------------------------
////infoarena heapuri
//https://www.infoarena.ro/problema/heapuri
//Fie o multime de numere naturale initial vida.
//Se cere sa se efectueze N operatii asupra acestei multimi, unde operatiile
// sunt de tipul celor de mai jos:
//
//operatia de tipul 1: se insereaza elementul x in multime
//operatia de tipul 2: se sterge elementul intrat al x-lea in multime,
//                     in ordine cronologica
//operatia de tipul 3: se afiseaza elementul minim din multime
#include <fstream>
#define M 200003
using namespace std;
ifstream fi("heapuri.in");
ofstream fo("heapuri.out");
int cine_este[M],unde_este[M];
int H[M],n,i,x,op,m,j,nr_el;
void schimba(int i,int j){
       swap(H[i],H[j]);
       swap(cine_este[i],cine_este[j]);
       unde_este[cine_este[i]]=i;
       unde_este[cine_este[j]]=j;
}
void InsertHeap(int n){//integreaza in minHeap elementul H[n]
  int i=n;
  while(i>=2 and H[i/2]>H[i]){ //se merge in sus pe MinHeap si
       schimba(i/2,i);
       i=i/2;
  }
}
int IndValMin(int i, int n){//determina indexul fiului cel mai mare al nodului i
                        //functia se apeleaza numai pentru noduri ce au 1 sau 2 fii(i<=n/2)
    if(2*i+1<=n)         // 2*i+1 este fiul dreapta a lui i (2*i+1<=n => i are doi fii)
        if(H[2*i]<=H[2*i+1])//daca nodul i are 2 fii
            return 2*i;    //daca fiul stang este mai mic
        else
            return 2*i+1;   //daca fiul drept este mai mic
    else
        return 2*i;     //daca nodul i  are fiu stanga
}
void Sterge(int i){ //sterge elementul H[i] din maxHeap   O(log(n))
  int p;          //adica aduce peste  H[i] elem. H[n] si reface minHeapul
       //merge in jos(cernere)pentru refacerea heapului
      schimba(i,n);
   n--;
  while(i<=n/2){        // i<=n adica daca i are fiu sau fii
    p=IndValMin(i,n);
    if(H[i]>H[p]){      //daca gaseste fiu mai mare
      schimba(i,p);
      i=p;              //continua cu fiul
      }
     else break;       //nu este fiu mai mare  Gata!
  }
}
void afisare(){
  int i;
  for(i=1;i<=nr_el;i++)fo<<H[i]<<" ";fo<<endl;
  for(i=1;i<=nr_el;i++)fo<<cine_este[i]<<" ";fo<<endl;
  for(i=1;i<=nr_el;i++)fo<<unde_este[i]<<" ";fo<<endl<<endl;
}
int main()
{
    fi >> m;
    for(i=1;i<=m;i++){
       fi >> op;
       if(op==1){
                 fi>>x;
                 nr_el++;
                 n++;
                 H[n]=x;
                 cine_este[n]=nr_el;
                 unde_este[nr_el]=n;
                 InsertHeap(n);
                 }
       if(op==2){ fi>>j; Sterge(unde_este[j]); }
       if(op==3){ fo<<H[1]<<'\n'; }
       //afisare();
    }
    fi.close(); fo.close();
    return 0;
}