Cod sursa(job #2897228)

Utilizator 4N70N1U5Antonio Nitoi 4N70N1U5 Data 2 mai 2022 23:11:43
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.12 kb
#include <iostream>
#include <fstream>
#include <utility>
#include <string>
#include <queue>
#include <set>
#include <cmath>

#define pair_pair std::pair<int, std::pair<int, int> > 

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

int x;
std::string input;
std::set<int> zeap;
// Zeap-ul este reprezentat in memorie ca un set, pe care l-am ales pentru ca 
// este o implementare a unui arbore binar de cautare.
std::priority_queue<pair_pair, std::vector<pair_pair>, std::greater<pair_pair> > dif;
// In acest priority queue de pair-uri stochez diferentele dintre doua elemente
// in ordine crescatoare si perechile de numere din care s-au obtinut. Primul element
// din pair este un int reprezentand diferenta, iar ce-al de-al doilea element
// este un alt pair care contine cele doua numere din care am obtinut-o. Pe acesta il
// voi folosi pentru a gasi rapid diferenta minima dintre doua numere.

void inserare()
{
    if (zeap.find(x) == zeap.end())
    {
        zeap.insert(x);
        std::set<int>::iterator i = zeap.find(x);
        if (i != zeap.begin())
        {
            i--;
            dif.push(std::make_pair(x - *i, std::make_pair(*i, x)));
            i++;
            // Introduc in pq diferenta dintre numarul inserat si
            // fiul lui stang, daca acesta exista (numarul inserat nu
            // este primul element din set).
        }
        if (++i != zeap.end())
        {
            dif.push(std::make_pair(*i - x, std::make_pair(x, *i)));
            // Introduc in pq diferenta dintre numarul inserat si
            // fiul lui drept, daca exista (numarul inserat nu este
            // ultimul din set).
        }
    }
}

void stergere()
{
    if (zeap.find(x) == zeap.end())
        fout << "-1\n";
    else
    {
        std::set<int>::iterator i = zeap.find(x);
        if (i != zeap.begin())
        {
            if (++i != zeap.end())
            {
                std::set<int>::iterator right = i--;
                std::set<int>::iterator left = --i;
                dif.push(std::make_pair(*right - *left, std::make_pair(*left, *right)));
                // Daca numarul pe care il voi sterge are doi fii, atunci introduc in pq
                // diferenta acestora, pentru ca altfel s-ar putea sa pierd diferenta
                // minima reala dupa stergerea elementului.
            }
        }
        zeap.erase(x);
    }
}

void cautare()
{
    if (zeap.find(x) != zeap.end())
        fout << "1\n";
    else
        fout << "0\n";
}

void max_dif()
{
    if (zeap.size() < 2)
        fout << "-1\n";
    else
        fout << *(--zeap.end()) - *(zeap.begin()) << '\n';
}

void min_dif()
{
    if (zeap.size() < 2)
        fout << "-1\n";
    else
    {
        while ((zeap.find(dif.top().second.first) == zeap.end() || zeap.find(dif.top().second.second) == zeap.end()))
            dif.pop(); // Sterg din fata pq-ul toate perechile care contin elemente sterse
        fout << dif.top().first << '\n';
    }
}

int main()
{
    while (std::getline(fin, input))
    {
        switch (input[0])
        {
        case 'I': // Operatie de inserare
            // Sterg "I " si transform rezultatul in int
            input.erase(input.begin(), input.begin() + 2);
            x = stoi(input);
            inserare();
            break;
        
        case 'S': // Operatie de stergere
            // Sterg "S " si transform rezultatul in int
            input.erase(input.begin(), input.begin() + 2);
            x = stoi(input);
            stergere();
            break;

        case 'C': // Operatie de cautare
            // Sterg "C " si transform rezultatul in int
            input.erase(input.begin(), input.begin() + 2);
            x = stoi(input);
            cautare();
            break;

        case 'M': // Operatie de afisare a diferentei minima sau maxima
            switch (input[1])
            {
            case 'A': // Diferenta maxima
                max_dif();
                break;

            case 'I': // Diferenta minima
                min_dif();
                break;
            
            default:
                break;
            }
            break;

        default:
            break;
        }
    }
}