Pagini recente » Cod sursa (job #434399) | Cod sursa (job #987380) | Cod sursa (job #711074) | Cod sursa (job #2692962) | Cod sursa (job #2622797)
//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;
}