Pagini recente » Cod sursa (job #1919828) | Cod sursa (job #2124803) | Istoria paginii runda/sin | Cod sursa (job #1121321) | Cod sursa (job #2750943)
#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;
}