Cod sursa(job #2750542)

Utilizator vali_27Bojici Valentin vali_27 Data 11 mai 2021 20:11:58
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.97 kb
/*
* o sa folosesc un set, unordered_map si priority queue din stl
* pt insereaza, sterge, cauta folosesc map ca sa 
* pt max-dif e practic diferenta dintre minimul si maximul curent pt asta folosesc set
* pt min-dif aici am folosit un min heap in care pun, dupa fiecare inserare a lui x,perechi: (predecesorul si x) si/sau (x si succesorul)
* ordonarea in heap se face dupa diferenta dintre cele 2 elemente din pereche
* la stergere lui x ma uit la elementul de dinainte si de dupa si pun perechea asta in heap pt ca nu exista inainte
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <set>
#include <queue>
#include <string>

std::ifstream fin("zeap.in");
std::ofstream fout("zeap.out");

struct Info {
	// unul e nr
	// celalat e predecesorul sau succesorul
	// dar mereu x < y
	int x, y;
};

struct Compare {
	bool operator()(const Info& i1, const Info& i2)
	{
		return i1.y - i1.x > i2.y - i2.x;
	}
};

std::unordered_map<int, bool> map;
std::priority_queue<Info, std::vector<Info>, Compare> heap;
std::set<int> set;

inline std::pair<int,int> getPredAndSucc(const std::set<int>& s, int x)
{
	int pred =-1, succ = -1;

	auto it = s.find(x);

	if (it != s.begin())
	{
		pred = *std::prev(it);
	}
	
	++it;
	if (it != s.end())
	{
		succ = *it;
	}

	return { pred,succ };

}

inline void Insert(int x)
{
	if (map[x] == false)
	{
		map[x] = true;
		set.insert(x);
	}
	auto pred_succ = getPredAndSucc(set, x);
	if (pred_succ.first != -1)
		heap.push({ pred_succ.first, x });

	if (pred_succ.second != -1)
		heap.push({ x,pred_succ.second });
}

inline void Delete(int x)
{
	if (map[x] == false)
	{
		fout << "-1\n";
		return;
	}
	map[x] = false;
	auto pred_succ = getPredAndSucc(set, x);

	set.erase(x);

	// nu sterg si din heap, fac un lazy delete
	// sterg din heap cand trebuie sa afisez din heap ceva
	// in schimb daca am nr:  a b c  si sterg b-ul atunci in heap 
	// trebuie sa bag c - a pt ca nu aveam informatia asta de dinainte
	if (pred_succ.first != -1 && pred_succ.second != -1)
		heap.push({ pred_succ.first, pred_succ.second });
}

inline bool Search(int x)
{
	return map[x];
}

inline int MaxDif()
{
	if (set.size() > 1)
		return *set.rbegin() - *set.begin();
	return -1;
}

inline int MinDif()
{	
	while (heap.size() && (map[heap.top().x] == false || map[heap.top().y] == false))
	{
		heap.pop();
	}
	if (heap.empty())return -1;

	return heap.top().y - heap.top().x;
}
 
int main()
{
	std::string input;
	int x;

	while (std::getline(fin, input))
	{
		std::cout << input << '\n';
		if (input[0] == 'I')
			Insert(std::stoi(input.c_str() + 2));
		else if (input[0] == 'S')
			Delete(std::stoi(input.c_str() + 2));
		else if (input[0] == 'C')
		{
			fout << Search(std::stoi(input.c_str() + 2)) << '\n';
		}
		else if (input[1] == 'A')
		{
			fout << MaxDif() << '\n';
 }
		else if (input[1] == 'I')
		{
			fout << MinDif() << '\n';
		}
	}
}