Cod sursa(job #2750943)

Utilizator Virgil993Virgil Turcu Virgil993 Data 13 mai 2021 17:35:12
Problema Zeap Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.54 kb
#include <iostream>
#include<bits/stdc++.h>

using namespace std;

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



struct Info {

    //In aceasta structua o sa tin minte perechi de forma (element ,succesor) si (predecesor, element)\
    //pentru a le retine intr-un priority queue ce va avea primul element pereachea ce are diferenta cea mai mica (MIN-dif)
	int x, y;

};


//structura ce ma ajuta sa suprascriu metoda de comparare a priority_queue-ului
struct Compara {
	bool operator()(Info& i1, Info& i2)

	{
		return i1.y - i1.x > i2.y - i2.x;
	}

};

// Am un map ce retine pentru fiecare element daca este sau nu in multime
//Si am un set ce retine toate elementele din multime pentru a returna repede (Max-dif)

unordered_map<int, bool> mp;
priority_queue<Info, vector<Info>, Compara> heap;
set<int> st;


//functie ce returneaza pereche de forma (predecesor,succesor) pentru un anumit element x dat
std::pair<int,int> getPredAndSucc(std::set<int>& s, int x)
{
	int pred = -1;
	int succ = -1;
	auto it = s.find(x);
	if (it != s.begin())
	{
		pred = *prev(it);
	}
	++it;
	if (it != s.end())
	{
		succ = *it;
	}
	return { pred,succ };

}



void Insert(int x)
{
    //daca nu este in multime atunci il inserez in set si apoi inserez predecesorii si succesorii lui in heap alaturi de el
	if (mp[x] == false)
	{
		mp[x] = true;
		st.insert(x);
	}
	auto pred_succ = getPredAndSucc(st, x);
	if (pred_succ.first != -1)
		heap.push({ pred_succ.first, x });
	if (pred_succ.second != -1)
		heap.push({ x,pred_succ.second });

}
void Delete(int x)
{
    //daca nu este in multime returnez -1
	if (mp[x] == false)
	{
		fout << "-1\n";
		return;

	}
    //daca este in multime, il scot din unordered_map si din set
	mp[x] = false;
	st.erase(x);

    auto pred_succ = getPredAndSucc(st, x);
    //de asemenea leg predecesor-ul de succesor in heap
    //voi elimina tot ce se leaga de x doar atunci cand vreau sa sterg ceva si x este in prima pereche din priority queue
	if (pred_succ.first != -1 && pred_succ.second != -1)
		heap.push({ pred_succ.first, pred_succ.second });


}



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

}



inline int MaxDif()
{
    //returnez diferenta intre primul si ultimul element din set
    //setul fiind sortat crescator si -1 daca setul nu are marimea mai mare sau egala ca 2
	if (st.size() > 1)
		return *st.rbegin() - *st.begin();
	return -1;

}
inline int MinDif()
{

    //eliminim din varf toate elementele ce au fost sterse anterior
    while(!heap.empty()&&(mp[heap.top().x]==false||mp[heap.top().y]==false))
        heap.pop();
    //daca priority queue este gol atunci returnam -1 pentru ca nu avem niciun predecesor si niciun succesor
	if (heap.empty())return -1;
    // altfel return diferenta din prima pereche din pq
    //pentru ca pq este sortat ca cea mai mica diferenta sa fie prima , acest lucru ne returneaza diferenta minima direct
	return abs(heap.top().y - heap.top().x);

}
int main()
{

	string input;
	int x;
	while (fin>>input)

	{

		cout << input << '\n';

		if (input == "I")
        {
                fin>>x;
                Insert(x);
        }

		else if (input == "S")
        {
            fin>>x;
            Delete(x);
        }
		else if (input == "C")

		{
            fin>>x;
			fout << Search(x) << '\n';

		}

		else if (input == "MAX")

		{

			fout << MaxDif() << '\n';

        }

		else if (input == "MIN")

		{

			fout << MinDif() << '\n';

		}

	}

	return 0;

}