Cod sursa(job #2650879)

Utilizator ViAlexVisan Alexandru ViAlex Data 20 septembrie 2020 17:29:06
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.94 kb
#include<iostream>
#include<fstream>

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

#define MAXNODES 200000

/*history[i] - the index of the element that was added i-th in the heap*/
int history[MAXNODES+1];

/*ind[i] - when was the element with the index i added in the heap*/
int ind[MAXNODES+1]; 

/*The number of insertions of values in the heap*/
int insertions=0;

/* A small heap representation:
 * Elements:{1,9,3,6,4,7,8}
 * 		 1
 *      / \
 *     /   \
 *    3     6 
 *   / \   / \
 *  /   \ 8   7 
 * 4     9
 * Each father node is smaller than its child nodes.
 */

/*Heap element count.*/
unsigned heap_size=0;

/*The heap buffer, holds the values*/
int heap[MAXNODES+1];

/*Returns the index of the father of the node.*/
inline int father(int node){
	return node/2;
}

/*Returns the index of the left son of the node*/
inline int lson(int node){
	return node*2;
}

/*Returns the index of the right son of the node*/
inline int rson(int node){
	return node*2+1;
}

/*Pretty-prints the heap*/
void print_heap(int node,std::string prefix,bool is_left){
	if(node>heap_size)
		return;
	std::cout<<prefix;
    std::cout << (is_left ? "├──" : "└──" );


	std::cout<<heap[node]<<std::endl;
	print_heap(lson(node),prefix+(is_left? "|  " : "   "),true);
	print_heap(rson(node),prefix+(is_left? "|  " : "   "),false);

}

/*Pushes the node downwards in the heap until the heap property is satisfied*/
void shift(int index){
	int next=0;
	int left=lson(index),right=rson(index);

	if(left<=heap_size){
		next=left;
		if(right<=heap_size && heap[right]<heap[left]){
			next=right;	
		}

		if(heap[next]<heap[index]){
			std::swap(heap[next],heap[index]);
			std::swap(history[ind[next]],history[ind[index]]);
			std::swap(ind[next],ind[index]);
			shift(next);
		}
	}		
}

/*Pushes the node upwards in the heap until the heap property is satisfied*/
void percolate(int index){
	int f=father(index);

	if(f!=0 && heap[index]<heap[f]){
		std::swap(heap[index],heap[f]);
		std::swap(history[ind[index]],history[ind[f]]);
		std::swap(ind[index],ind[f]);
		percolate(f);
	}

}

/*Inserts a new value into the heap*/
void insert(int value){
	heap[heap_size+1]=value;
	history[insertions]=heap_size+1;
	ind[heap_size+1]=insertions;

	insertions++;

	percolate(heap_size+1);
	heap_size++;
}


/*Removes the node from the heap*/
void remove(int index){
	heap[index]=heap[heap_size];
	std::swap(history[ind[index]],history[ind[heap_size]]);
	std::swap(ind[index],ind[heap_size]);

	heap_size--;
	
	int f=father(index);

	if(f!=0 && heap[index]<heap[f]){
		percolate(index);
	}
	else{
		shift(index);
	}

}

/*Returns the smallest value in the heap*/
inline int smallest(){
	return heap[1];
}


void remove_ith(int i){
	remove(history[i-1]);
}





int main(){
	int num_queries,a,b;
	in>>num_queries;
	for(int i=0;i<num_queries;i++){
		in>>a;
		if(a==1){
			in>>b;
			insert(b);
		}
		else if(a==2){
			in>>b;
			remove_ith(b);
		}
		else{
			out<<smallest()<<'\n';
		}


	}
	return 0;
}