Cod sursa(job #2758558)

Utilizator lucamLuca Mazilescu lucam Data 11 iunie 2021 00:11:49
Problema Zeap Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.08 kb
#include <unordered_map>
#include <fstream>
#include <limits>

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

#define INF std::numeric_limits<int>::max()
#define MINF std::numeric_limits<int>::min()

const int N = 1 << 20;
const int NN = 3e5;
struct Interval {
    int max;
    int min;
    int min_diff;
} v[N + 1];
std::unordered_map<int, int> m;

static int g_pos;
static Interval g_val;

int update_impl(int node = 1, int l = 1, int r = NN) {
    if (l == r) {
        v[node] = g_val;
        return node;
    }
    int m = (l + r) / 2;
    int ret;
    if (g_pos <= m) {
        ret = update_impl(2 * node, l, m);
    } else {
        ret = update_impl(2 * node + 1, m + 1, r);
    }
    auto &left = v[2 * node];
    auto &right = v[2 * node + 1];
    v[node].max = std::max(left.max, right.max);
    v[node].min = std::min(left.min, right.min);
    bool init_left = left.min_diff != MINF;
    bool init_right = right.min_diff != MINF;
    if (init_left && init_right) {
        if (r - l > 1) {
            v[node].min_diff = std::min(left.min_diff, right.min_diff);
        }
        else {
            v[node].min_diff = std::abs(left.max - right.max);
        }
    }
    else if (init_left) {
        v[node].min_diff = left.min_diff;
    }
    else {
        v[node].min_diff = right.min_diff;
    }
    return ret;
}

void update_downtop(int node) {
    v[node].max = std::max(v[2 * node].max, v[2 * node + 1].max);
    v[node].min = std::min(v[2 * node].min, v[2 * node + 1].min);
    v[node].min_diff = std::min(v[2 * node].min_diff, v[2 * node + 1].min_diff);
    if (node != 1) {
        update_downtop(node / 2);
    }
}

inline void append(int val) {
    if (m.find(val) != m.end()) {
        return;
    }
    g_val = {val, val, MINF};
    ++g_pos;
    m[val] = update_impl();
}

void remove(int val) {
    if (m.find(val) == m.end()) {
        out << "-1\n";
        return;
    }
    int node = m[val];
    v[node] = {MINF, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()};
    m.erase(val);
    update_downtop(node / 2);
}

int str_to_int(const char *s) {
    int x = 0;
    while (isdigit(*s)) {
        x = x * 10 + *s - '0';
        ++s;
    }
    return x;
}

int main() {
    for (int i = 1; i <= N; ++i) {
        v[i].min_diff = std::numeric_limits<int>::max();
        v[i].max = std::numeric_limits<int>::min();
        v[i].min = INF;
    }
    char line[15];
    while (in.getline(line, 15)) {
        int x = 0;
        if (line[1] == ' ') {
            x = str_to_int(line + 2);
        }
        switch (*line) {
        case 'I':
            append(x);
            break;
        case 'S':
            remove(x);
            break;
        case 'C':
            out << (m.find(x) != m.end()) << '\n';
            break;
        case 'M':
            if (line[1] == 'A') {
                out << v[1].max - v[1].min << '\n';
            }
            else {
                out << v[1].min_diff << '\n';
            }
            break;
        }
    }
}