#include <stdio.h>
#include <stdlib.h>
const unsigned int maxop = 200000;
const unsigned int maxelem = 1000000000;
int pozIntrare[200000];
int pozHeap[200000], poz;
unsigned int nrIntrari;
void afiseaza(unsigned int *heap, unsigned int dim) {
unsigned int i=0;
for(;i<dim; i++) {
printf("%u ", heap[i]);
}
printf("\n");
}
//void refaHeap(unsigned int *heap, unsigned int start, unsigned int stop){
void refaHeap(unsigned int *heap, unsigned int start, unsigned int stop, unsigned int elem){
unsigned int index=start;
short int eHeap=0;
unsigned int temp;
while((2*index+1 < stop) && !eHeap) {
unsigned int copil = 2*index+1;
if ((copil < stop-1) && (heap[copil] > heap[copil+1])) copil++;
if (heap[index] > heap[copil]) {
temp = heap[index]; heap[index] = heap[copil]; heap[copil] = temp;
pozHeap[heap[index]] = index;
pozHeap[heap[copil]] = copil;
index = copil;
}
else {
pozHeap[heap[index]] = index;
pozHeap[heap[copil]] = copil;
eHeap=1;
}
}
pozHeap[elem]=poz;
//printf("Pozitia finala: %u (pt elem %u)\n", poz,elem);
}
void insereaza(unsigned int *heap, unsigned int *dim, unsigned int elem) {
//daca heap-ul e gol, punem elementul ca radacina si incrementam contorul nrelem;
if (*dim == 0 ) {
heap[0] =elem;
*dim+=1;
pozIntrare[nrIntrari++]=elem;
pozHeap[elem]=0;
}
else if (*dim < maxelem) {
*dim+=1; // facem loc pentru noul element
heap[*dim-1]=elem; //pun elementul de inserat pe ultima pozitie din heap
pozIntrare[nrIntrari++]=elem;
int i=(*dim-1)/2;
//refac heap-ul
//printf("Vrei sa inserez elem %u\n", elem);
poz=-1;
for(;i>=0; i--)
//refaHeap(heap, i, *dim);
refaHeap(heap, i, *dim,elem);
}
else // am umplut heap-ul
return;
}
void elimina(unsigned int *heap, unsigned int *dim, unsigned int pozelem) {
// intai luam elementul care-a fost inserat pe pozitia respectiva
int elem = pozIntrare[pozelem-1];
if(elem == -1) return;
//afiseaza(heap, *dim);
//printf("Vrei sa-l elimin pe %u (poz %u in heap)\n", elem, pozHeap[elem]);
//gasesc pozitia in heap a elementului pe care vreau sa-l elimin
unsigned int i;
i=pozHeap[elem];
if(i==-1) return;
//printf("De pe pozitia %u in heap!\n", i);
unsigned int temp;
temp=heap[*dim-1]; heap[*dim-1]=heap[i]; heap[i]=temp; // swap
*dim-=1;
int j=(*dim-1)/2;
//refac heap-ul
for(;j>=0; j--)
refaHeap(heap, j, *dim,-1);
pozIntrare[pozelem-1]=-1;
//printf("Eliminat!\n");
//afiseaza(heap, *dim);
}
int main() {
//FILE *fisin, *fisout;
unsigned int c1, c2, nrop, nrelem=0;
unsigned int heap[100000];
int l;
freopen("heapuri.in", "r", stdin);
freopen("heapuri.out", "w", stdout);
//if ((fisin = fopen("heapuri.in", "r")) == NULL)
//exit(1);
//if ((fisout = fopen("heapuri.out", "w")) == NULL)
// exit(1);
scanf("%u", &nrop);
if (nrop > maxop && 1 <= nrop) // 1<= N<=200.000
exit(1);
for(l=1;l<=nrop;l++) {
scanf("%u", &c1);
switch (c1) {
case 1:
scanf("%u", &c2);
//inserez elementul c2 in heap
if (c2 > maxelem)
exit(1);
insereaza(heap, &nrelem, c2);
break;
case 2:
scanf("%u", &c2);
//sterg elementul de pe pozitia specificata de c2
elimina(heap, &nrelem, c2);
//afiseaza(heap, nrelem);
break;
case 3:
//afisez elementul minim din heap, adica radacina
printf("%u\n", heap[0]);
break;
default:
exit(1);
break;
}
}
//afiseaza(pozIntrare, nrIntrari);
//printf("Total elemente: %u\n", nrelem);
//fclose(fisin);
//fclose(fisout);
return 0;
}