Cod sursa(job #2751923)

Utilizator SteFUNGrigorescu Stefan Dumitru SteFUN Data 16 mai 2021 04:14:14
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <iostream>
#include <fstream>
#include <string>
#include <queue>
#include <set>
#include <vector>
#include <cmath>

std::ifstream f("zeap.in");
std::ofstream g("zeap.out");


std::set <int> zeap;

struct distanta
{
	int predecesor;
	int succesor;
	distanta(int p, int s)
	{
		predecesor = p;
		succesor = s;
	}
};

struct cmp_for_distante
{
	bool operator() (distanta a, distanta b)     //  pq tine in radacina ultimul elem returnat de aici (cel cu distanta minima)
	{
		return (a.succesor - a.predecesor) > (b.succesor - b.predecesor);
	}
};
std::priority_queue<distanta, std::vector<distanta>, cmp_for_distante> distante;

void inserare(int x)
{
	if( zeap.count(x) == 0)
	{
		zeap.insert(x);
		std::set<int>::iterator poz = zeap.find(x), succ = poz;
		succ++;
		if (succ != zeap.end())
			distante.push(distanta(x, *succ));

		if (poz != zeap.begin())      // adica are predecesor
		{
			std::set<int>::iterator pred = poz;
			pred--;
			distante.push(distanta(*pred, x));
		}
	}
}

int stergere(int x)
{
	std::set<int>::iterator poz = zeap.find(x);
	if (poz == zeap.end())
		return -1;

	std::set<int>::iterator succ = poz, pred = poz;
	succ++;
	pred--;
	if (succ != zeap.end() and poz != zeap.begin())    //  adica are succesor si predecesor
		distante.push(distanta(*pred, *succ));

	zeap.erase(x);
	return 1;
}

bool cauta(int x)
{
	return zeap.count(x);
}

int maxima()
{
	if (zeap.empty())
		return -1;

	std::set<int>::iterator primul = zeap.begin(), ultimul = zeap.end();
	ultimul--;
	if (primul == ultimul)
		return -1;

	return *ultimul - *primul;
}

int minima()
{
	if (zeap.empty())
		return -1;
	                              // cat timp avem elemente sterse in distante
	while (!distante.empty() and  ( !zeap.count(distante.top().predecesor) or !zeap.count(distante.top().succesor)) )	   
		distante.pop();   //   stergem respectivele distante inactuale prin lazy deletion

	if (!distante.empty())
		return fabs(distante.top().succesor - distante.top().predecesor);

	return -1;
}

int main()
{
	std::string comanda;
	int  x;
	while (f >> comanda)
	{
		if (comanda[0] == 'I')				// insereaza x
		{
			f >> x;
			inserare(x);
		}
		else if (comanda[0] == 'S')		// sterge x
		{
			f >> x;
			if (stergere(x) == -1)
				g << "-1\n";
		}
		else if (comanda[0] == 'C')		// cauta x
		{
			f >> x;
			g << cauta(x) << "\n";
		}
		else if (comanda[1] == 'A')		// max-dif
		{
			g << maxima() << "\n";
		}
		else											// min-dif
		{
			g << minima() << "\n";
		}
	}

	return 0;
}