Cod sursa(job #3135153)

Utilizator LazarDanielGabrielLazar Daniel-Gabriel LazarDanielGabriel Data 2 iunie 2023 01:23:25
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.47 kb
#include <iostream>
#include <fstream>
#include <set>
#include <queue>
#include <cmath>
using namespace std;

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

struct Pair
{
    int a, b;
    Pair(int a = 0, int b = 0)
    {
        this->a = a;
        this->b = b;
    }

    Pair& operator=(const Pair& per)
    {
        if (this != &per)
        {
            this->a = per.a;
            this->b = per.b;
        }
        return *this;
    }

    bool operator<(const Pair& per) const
    {
        return abs(this->a - this->b) < abs(per.a - per.b);
    }

    bool operator>(const Pair& per) const
    {
        return abs(this->a - this->b) > abs(per.a - per.b);
    }
};

priority_queue<Pair, vector<Pair>, greater<Pair>> pairPriorityQueue;
set<int> numberSet;

void updatePair(int x)
{
    int minimum = 1000000010, number = x;
    auto it = numberSet.find(x);
    if (it != numberSet.end())
    {
        if (it != numberSet.begin())
        {
            auto predecessor = it;
            --predecessor;
            minimum = abs(x - *predecessor);
            number = *predecessor;
        }
        if (++it != numberSet.end())
        {
            auto successor = it;
            if (abs(x - *successor) < minimum)
                number = *successor;
        }
    }
    if (number != x)
        pairPriorityQueue.push(Pair(x, number));
}

void insertNumber(int x)
{
    if (!numberSet.count(x))
    {
        numberSet.insert(x);
        updatePair(x);
    }
}

int removeNumber(int x)
{
    if (numberSet.count(x))
    {
        auto it = numberSet.find(x);
        auto predecessor = it;
        auto successor = it;

        if (it != numberSet.begin())
        {
            auto predecessor = it;
            --predecessor;
        }
        if (++successor != numberSet.end())
        {
            pairPriorityQueue.push(Pair(*predecessor, *successor));
        }

        numberSet.erase(x);
        return 1;
    }
    return -1;
}

int searchNumber(int x)
{
    return numberSet.count(x);
}

int maxDifference()
{
    if (numberSet.size() < 2)
        return -1;
    auto minimum = numberSet.begin();
    auto maximum = numberSet.rbegin();
    return abs(*minimum - *maximum);
}

int minDifference()
{
    if (numberSet.size() < 2)
        return -1;

    Pair x = pairPriorityQueue.top();
    while (!numberSet.count(x.a) || !numberSet.count(x.b))
    {
        pairPriorityQueue.pop();
        if (numberSet.count(x.a))
            updatePair(x.a);
        else if (numberSet.count(x.b))
            updatePair(x.b);
        x = pairPriorityQueue.top();
    }
    return abs(x.a - x.b);
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    string command;
    int x;
    while (fin >> command)
    {
        if (command == "I")
        {
            fin >> x;
            insertNumber(x);
        }
        else if (command == "S")
        {
            fin >> x;
            int val = removeNumber(x);
            if (val == -1)
                fout << -1 << "\n";
        }
        else if (command == "C")
        {
            fin >> x;
            fout << searchNumber(x) << "\n";
        }
        else if (command == "MAX")
        {
            fout << maxDifference() << "\n";
        }
        else if (command == "MIN")
        {
            fout << minDifference() << "\n";
        }
    }

    return 0;
}