Pagini recente » Cod sursa (job #2771314) | Cod sursa (job #3041598) | Cod sursa (job #1998651) | Cod sursa (job #1940883) | Cod sursa (job #2899093)
#include <fstream>
#include <queue>
#include <set>
#include <tuple>
class Zeap {
std::set<int> set;
using Diff = std::tuple<int, int, int>;
std::priority_queue<Diff, std::vector<Diff>, std::greater<Diff>> diff_heap;
std::pair<decltype(set)::iterator, decltype(set)::iterator>
find_neighbors(decltype(set)::iterator x_iter) {
return {std::prev(x_iter), std::next(x_iter)};
}
public:
void insert(int x) {
set.insert(x);
auto x_iter = set.find(x);
auto neighbors = find_neighbors(x_iter);
auto pred = neighbors.first;
auto succ = neighbors.second;
if (x_iter != set.begin()) {
diff_heap.push({x - *pred, x, *pred});
}
if (succ != set.end()) {
diff_heap.push({*succ - x, *succ, x});
}
}
bool erase(int x) {
auto x_iter = set.find(x);
if (x_iter == set.end()) {
return false;
}
auto neighbors = find_neighbors(x_iter);
auto pred = neighbors.first;
auto succ = neighbors.second;
if (x_iter != set.begin() && succ != set.end()) {
diff_heap.push({*succ - *pred, *succ, *pred});
}
set.erase(x_iter);
return true;
}
bool contains(int x) { return set.find(x) != set.end(); }
int max_diff() {
if (set.size() < 2) {
return -1;
}
return *set.rbegin() - *set.begin();
}
int min_diff() {
auto invalidated_diff = [&](const std::tuple<int, int, int> &diff) {
auto term1 = std::get<1>(diff);
auto term2 = std::get<2>(diff);
return set.find(term1) == set.end() || set.find(term2) == set.end();
};
// Ignore diffs whose terms are no longer in the set
while (!diff_heap.empty() && invalidated_diff(diff_heap.top())) {
diff_heap.pop();
}
if (diff_heap.empty()) {
return -1;
}
return std::get<0>(diff_heap.top());
}
};
int main() {
std::ifstream ifs("zeap.in");
std::ofstream ofs("zeap.out");
Zeap zeap;
std::string action;
while (ifs >> action) {
if (action == "MAX") {
ofs << zeap.max_diff() << '\n';
} else if (action == "MIN") {
ofs << zeap.min_diff() << '\n';
} else {
int x;
ifs >> x;
if (action == "I") {
zeap.insert(x);
} else if (action == "S") {
if (!zeap.erase(x)) {
ofs << "-1\n";
}
} else if (action == "C") {
ofs << (zeap.contains(x) ? 1 : 0) << '\n';
}
}
}
ofs.close();
ifs.close();
return 0;
}