Cod sursa(job #912797)

Utilizator h2g2Ford Prefect h2g2 Data 12 martie 2013 19:27:29
Problema Heapuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#define nmax 200005
using namespace std;

//v[i]   = a i-a valoare
//h[i]   = pozitia din v[] care se afla aici in heap
//pos[i] = pozitia in heap care corespunde lui v[i]

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

int v[nmax], h[nmax], pos[nmax];
int n=0, op, x, cnt = 0;

int father(int nod) { return(nod / 2); }
int left_son(int nod) { return(nod * 2); }
int right_son(int nod) { return(nod * 2 + 1); }
int minim() { return(v[h[1]]); }

int sift(int nod) {
	//posibil ca nodul curent sa fie mai mare decat fiii lui, caz in care trebuie coborat in heap
	int substitute = -1;
	
	if(left_son(nod) <= n) substitute = left_son(nod);
	if(right_son(nod) <= n) {
		if(substitute == -1) substitute = right_son(nod);
		else if(v[h[right_son(nod)]] < v[h[left_son(nod)]]) substitute = right_son(nod);
	}
	
	if(substitute == -1) return 0;
	
	if(v[h[nod]] < v[h[substitute]]) {
		//trebuie sa interschimb "nod" si "substitute"


		swap(pos[h[nod]], pos[h[substitute]]);
		
		swap(h[nod], h[substitute]);
		sift(substitute);
	}
	
	return 0;
}

int percolate(int nod) {
	//posibil ca nodul curent sa fie mai mic decat padrele lui, caz in care trebuie urcat in heap
	
	if(nod == 1) return 0;		//ii ca si luke, nu are tata
	
	int substitute = father(nod);
	
	if(v[ h[nod] ] >= v[ h[substitute] ]) return 0;		//proprietatea de heap ii pastrata
	
	pos[ h[nod] ] = substitute;
	pos[ h[substitute] ] = nod;
	
	swap(h[nod], h[substitute]);
	swap(pos[h[nod]], pos[h[substitute]]);
	
	percolate(substitute);
	
	return 0;
}

int insert(int i) {
	n++;
	f>>v[n];
	h[cnt] = n;
	pos[n] = cnt;
	
	percolate(i);
	
	return 0;
}

int remove(int nod) {
	h[nod] = h[n];
	pos[ h[n] ] = pos[ h[nod] ];
	
	n--;
	
	if(v[h[nod]] < v[h[ father(nod) ]]) percolate(nod);
	else sift(nod);
	
}

int main() {
	
	int dim, temp;
	f>>dim;
	while(dim--) {
		f>>op;
		
		if(op==3) {
			g<<minim()<<"\n";
			continue;
		}
		
		if(op==2) { 
			f>>temp;
			//cout<<"vrei sa stergi valoarea "<<v[h[ pos[temp] ]]<<" aflata la pozitia "<<pos[temp]<<" in heap\n";
			remove(pos[temp]);
		}
		
		if(op==1) { cnt++; insert(cnt); }
		
		//for(int j=1; j<=n; j++) cout<<v[h[j]]<<" "; cout<<"\n";
	}
	
	
	return 0;
}