Cod sursa(job #3262303)

Utilizator vlad_binVlad Bintintan vlad_bin Data 9 decembrie 2024 17:49:55
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.21 kb
#include <bits/stdc++.h>

using namespace std;

const int NMax = 100005;

inline int dist(int a, int b) {
    return b - a + 1;
}

inline int dist(pair<int, int> p) {
    return dist(p.first, p.second);
}

struct room {
    int free_prefix, free_max, free_suffix;
    bool lazy;

    using interval = pair<int, int>;
    using room_interval = pair<interval, const room&>;
    
    room(int free_prefix, int free_max, int free_suffix, bool lazy = false) :
        free_prefix(free_prefix),
        free_max(free_max),
        free_suffix(free_suffix),
        lazy(lazy) {}
    
    room(int elements, bool lazy = true): room(elements, elements, elements, lazy) {}

    room() = default;
} rooms[4 * NMax];

room mconcat(const room::room_interval& a, const room::room_interval& b) {
    auto [left_interval, left_rooms] = a;
    auto [right_interval, right_rooms] = b;

    auto left_size = dist(left_interval);
    auto right_size = dist(right_interval);

    int free_prefix = left_rooms.free_prefix, free_suffix = right_rooms.free_suffix, free_max;

    if (free_prefix == left_size)
        free_prefix += right_rooms.free_prefix;
    
    if (free_suffix == right_size)
        free_suffix += left_rooms.free_suffix;

    free_max = ranges::max({free_prefix, free_suffix, left_rooms.free_max, right_rooms.free_max, left_rooms.free_suffix + right_rooms.free_prefix});

    return room(free_prefix, free_max, free_suffix);
}

int x, y;

void set_rooms(int node, int l, int r) {
    if (y < l || r < x)
        return;
    if (x <= l && r <= y) {
        rooms[node] = room(0);
        return;
    }

    int mij = (l + r) / 2;

    if (rooms[node].lazy) {
        rooms[node].lazy = false;

        bool empty = rooms[node].free_max != 0;
        int left_elements = dist(l, mij) * empty;
        int right_elements = dist(mij + 1, r) * empty;

        rooms[node * 2] = room(left_elements);
        rooms[node * 2 + 1] = room(right_elements);
    }

    set_rooms(node * 2, l, mij);
    set_rooms(node * 2 + 1, mij + 1, r);

    rooms[node] = mconcat({{l, mij}, rooms[node * 2]}, {{mij + 1, r}, rooms[node * 2 + 1]});
}

void empty_rooms(int node, int l, int r) {
    if (y < l || r < x)
        return;
    if (x <= l && r <= y) {
        rooms[node] = room(dist(l, r));
        return;
    }

    int mij = (l + r) / 2;

    if (rooms[node].lazy) {
        rooms[node].lazy = false;

        bool empty = rooms[node].free_max != 0;
        int left_elements = dist(l, mij) * empty;
        int right_elements = dist(mij + 1, r) * empty;

        rooms[node * 2] = room(left_elements);
        rooms[node * 2 + 1] = room(right_elements);
    }

    empty_rooms(node * 2, l, mij);
    empty_rooms(node * 2 + 1, mij + 1, r);

    rooms[node] = mconcat({{l, mij}, rooms[node * 2]}, {{mij + 1, r}, rooms[node * 2 + 1]});
}

int main() {
    ifstream cin("hotel.in");
    ofstream cout("hotel.out");

    int n, m;
    cin >> n >> m;
    
    rooms[1] = room(n);

    for (int i = 0; i < m; i++) {
        int op;
        cin >> op;
        if (op == 3) {
            cout << rooms[1].free_max << endl;
            continue;
        }
        cin >> x >> y;

        y += x - 1;

        if (op == 1)
            set_rooms(1, 1, n);
        else
            empty_rooms(1, 1, n);
    }
}