Cod sursa(job #3233030)

Utilizator sireanu_vladSireanu Vlad sireanu_vlad Data 2 iunie 2024 11:45:21
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.04 kb
#include <iostream>
#include <vector>
using namespace std;

class Hotel {
public:
    int n;
    struct Node {
        int max_free;
        int max_left;
        int max_right;
        bool same_below;
    };
    vector<Node> arbint;
    int arbsize;

    void read() {
        cin >> n;

        arbsize = 1;
        while (arbsize < n) {
            arbsize *= 2;
        }
        arbint.resize(2 * arbsize);

        arbint[1] = Node{ n, n, n, true };
    }
    void check_in(int i, int m) {
        update(1, 1, n, i, i + m - 1, true);
    }
    void check_out(int i, int m) {
        update(1, 1, n, i, i + m - 1, false);
    }
    void update(int node, int l, int r, int s, int f, bool arrival) {
        if (s <= l && r <= f) {
            if (arrival) {
                arbint[node] = Node{ 0, 0, 0, true };
            } else {
                arbint[node] = Node{ r - l + 1, r - l + 1, r - l + 1, true };
            }
        } else {
            int m = (l + r) / 2;
            int left = 2 * node;
            int right = 2 * node + 1;

            if (arbint[node].same_below) {
                if (arbint[node].max_free > 0) {
                    arbint[left] = Node{ m - l + 1, m - l + 1, m - l + 1, true };
                    arbint[right] = Node{ r - m, r - m, r - m, true };
                } else {
                    arbint[left] = Node{ 0, 0, 0, true };
                    arbint[right] = Node{ 0, 0, 0, true };
                }

                arbint[node].same_below = false;
            }

            if (s <= m) {
                update(left, l, m, s, f, arrival);
            }
            if (m < f) {
                update(right, m + 1, r, s, f, arrival);               
            }

            arbint[node].max_free = max(max(arbint[left].max_free, arbint[right].max_free), arbint[left].max_right + arbint[right].max_left);

            if (arbint[left].max_left == m - l + 1) {
                arbint[node].max_left = (m - l + 1) + arbint[right].max_left;
            } else {
                arbint[node].max_left = arbint[left].max_left;
            }

            if (arbint[right].max_right == r - m) {
                arbint[node].max_right = arbint[left].max_right + (r - m);
            } else {
                arbint[node].max_right = arbint[right].max_right;
            }
        }
    }
    int max_free() {
        return arbint[1].max_free;
    }
};

int main() {
    freopen("hotel.in", "r", stdin);
    freopen("hotel.out", "w", stdout);

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    Hotel hotel;
    hotel.read();

    int p;
    cin >> p;

    while (p--) {
        int c;
        cin >> c;

        if (c == 1 || c == 2) {
            int i, m;
            cin >> i >> m;

            if (c == 1) {
                hotel.check_in(i, m);
            } else if (c == 2) {
                hotel.check_out(i, m);
            }
        } else if (c == 3) {
            cout << hotel.max_free() << '\n';
        }
    }
}