Pagini recente » Cod sursa (job #1122383) | Cod sursa (job #76388) | Cod sursa (job #2757000) | Cod sursa (job #1234276) | Cod sursa (job #2750542)
/*
* 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';
}
}
}