Cod sursa(job #1231120)

Utilizator tudorv96Tudor Varan tudorv96 Data 19 septembrie 2014 17:11:20
Problema Zeap Scor 80
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Semestrul 2 Marime 3.31 kb
#include <fstream>
#include <set>
using namespace std;

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

char P[1 << 20], *now = P;

set <int> S;
multiset <int> dif;
set <int> :: iterator downLim, upLim;
set <int> :: reverse_iterator upper;
int nr;

void parse() {
    if (*now)
        return;
    fin.get(P, (1 << 20) - 1, '\0');
    now = P;
}

int get() {
    int x = 0;
    while (*now < '0' || *now > '9')
        ++now, parse();
    while (*now >= '0' && *now <= '9') {
        x = x * 10 + *now - '0';
        ++now, parse();
    }
    return x;
}

int main() {
    parse();
    while (1) {
        ++nr;
        if (!(*now)) {
            parse();
            if (!(*now))
                return 0;
        }
        if (*now == 'M') {
            ++now, parse();
            ++now, parse();
            if (*now == 'N') { //MINIM
                if (dif.size())
                    fout << *dif.begin() << "\n";
                else
                    fout << "-1\n";
            }
            if (*now == 'X') { //MAXIM
                if (S.size() >= 2) {
                    upper = S.rbegin();
                    downLim = S.begin();
                    fout << *upper - *downLim << "\n";
                }
                else
                    fout << "-1\n";
            }
        }
        else
            if (*now == 'I') {
                int x = get(), sol = -1;
                if (S.find(x) == S.end()) {
                    S.insert(x);
                    upLim = S.upper_bound(x);
                    for (int step = 1 << 30; step; step >>= 1) {
                        set <int> :: iterator it = S.upper_bound (sol + step);
                        if (it != S.end() && *it < x)
                            sol += step;
                    }
                    sol++;
                    if (upLim != S.end() && sol)
                        dif.erase (dif.find(*upLim - sol));
                    if (sol)
                        dif.insert (x - sol);
                    if (upLim != S.end())
                        dif.insert (*upLim - x);
                }
            }
        else
            if (*now == 'S') {
                int x = get(), sol = -1;
                if (S.find(x) == S.end())
                    fout << "-1\n";
                else {
                    upLim = S.upper_bound(x);
                    for (int step = 1 << 30; step; step >>= 1) {
                        set <int> :: iterator it = S.upper_bound (sol + step);
                        if (it != S.end() && *it < x)
                            sol += step;
                    }
                    sol++;
                    if (upLim != S.end() && sol)
                        dif.insert (*upLim - sol);
                    if (sol)
                        dif.erase (dif.find(x - sol));
                    if (upLim != S.end())
                        dif.erase (dif.find(*upLim - x));
                    S.erase(x);
                }
            }
        else
            if (*now == 'C') {
                int x = get();
                downLim = S.find(x);
                if (downLim != S.end())
                    fout << "1\n";
                else
                    fout << "0\n";
            }
        ++now, parse();
    }
}