Cod sursa(job #1331730)

Utilizator charmpitzAndrei Pit charmpitz Data 1 februarie 2015 01:24:32
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.01 kb

/*
Enunt:
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
Date de intrare
Fisierul de intrare heapuri.in va contine pe prima linie numarul N. Pe urmatoarele N linii se va afla descrierea operatiilor care trebuie efectuate. Primul numar de pe fiecare linie, cod, reprezinta tipul operatiei. Daca cod este 1 sau 2, atunci linia corespunzatoare va mai contine si numarul x, avand semnificatia din enunt.

Date de ieşire
Fisierul de iesire heapuri.out va contine, pe cate o linie, raspunsul pentru fiecare operatie de tipul 3 din fisierul de intrare, in ordinea data.

Restricţii
1 ≤ N ≤ 200 000
Elementele multimii nu vor depasi 1 000 000 000
Se garanteaza ca nu se va cere niciodata sa se afle minimul daca multimea este vida
Se garanteaza ca nu vor exista 2 operatii de tipul 2 care sa stearga acelasi element din multime
Pentru o operatie de tipul 2 se va sterge un element care e deja intrat in multime
Exemplu

heapuri.in	
9
1 4 
1 7 
1 9
3
1 2
2 1
3
2 4
3

heapuri.out
4 
2
7
Explicatie
Dupa primele 3 operatii vom avea in multime elementele 4, 7 si 9. Astfel raspunsul la operatia de tip 3 este 4. In continuare vom adauga elementul 2 si vom sterge primul element inserat, adica 4, ramanand cu elementele 2, 7 si 9. Vom sterge apoi al 4-lea element intrat, adica 2, in multime aflandu-se la sfarsit numai 7 si 9, minimul fiind 7.
*/

/*
Rezolvare:

*/


#include <stdio.h>

FILE *in, *out;

struct per {
	int val, pos;
};

int n, pos[200001];
per x[200001], aux;


int main ()
{
	int i, j, act, val, c, nx, loc, min, pj;
	
	in = fopen("heapuri.in", "r");
	out = fopen("heapuri.out", "w");

	fscanf(in, "%d", &n);

	nx = 0;
	c = 0;

	for (i=1; i<=n; i++)
	{
		fscanf(in, "%d", &act);

		switch(act)
		{
			case 1:
				fscanf(in, "%d", &val);
				
				c++;
				nx++;
				x[nx].val = val;
				x[nx].pos = c;
				pos[c] = nx;

				j = nx;
				while ((j > 1) && (x[j/2].val > x[j].val))
				{
					aux = x[j];
					x[j] = x[j/2];
					x[j/2] = aux;
					
					pos[x[j/2].pos] = j/2;
					pos[x[j].pos] = j;
					j = j/2;
				}

 				break;
			case 2:
				fscanf(in, "%d", &loc);
				
				j = pos[loc];
				
				x[j] = x[nx];
				pos[x[nx].pos] = j;
				nx--;

				while (j*2 <= nx)
				{
					min = 2000000000;
					if ((j*2 <= nx) && (x[j*2].val < min))
					{
						min = x[j*2].val;
						pj = j*2;
					}

					if ((j*2+1 <=nx) && (x[j*2+1].val < min))
					{
						min = x[j*2+1].val;
						pj = j*2+1;
					}

					if (x[j].val > min)
					{
						aux = x[j];
						x[j] = x[pj];
						x[pj] = aux;
						
						pos[x[pj].pos] = pj;
						pos[x[j].pos] = j;
						j = pj;
					}
					else
					{
						break;
					}

				}
				

				break;
			case 3:
				fprintf(out, "%d\n", x[1].val);

				break;
		}
	}

	
	fclose(out);
	fclose(in);

	return 0;
}