Cod sursa(job #3233158)

Utilizator AndreiDocaDoca Andrei AndreiDoca Data 2 iunie 2024 17:52:20
Problema Hotel Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.53 kb
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Node {
    int max_free;
    int left_free;
    int right_free;
    int total_free;
};

vector<Node> tree;
int n;

void merge(int node, int start, int end) {
    int mid = (start + end) / 2;
    int left_child = 2 * node;
    int right_child = 2 * node + 1;
    
    tree[node].left_free = tree[left_child].left_free;
    tree[node].right_free = tree[right_child].right_free;
    
    if (tree[left_child].total_free == mid - start + 1) {
        tree[node].left_free += tree[right_child].left_free;
    }
    
    if (tree[right_child].total_free == end - mid) {
        tree[node].right_free += tree[left_child].right_free;
    }
    
    tree[node].total_free = tree[left_child].total_free + tree[right_child].total_free;
    tree[node].max_free = max({tree[left_child].max_free, tree[right_child].max_free, tree[left_child].right_free + tree[right_child].left_free});
}

void build(int node, int start, int end) {
    if (start == end) {
        tree[node] = {1, 1, 1, 1};
    } else {
        int mid = (start + end) / 2;
        build(2 * node, start, mid);
        build(2 * node + 1, mid + 1, end);
        merge(node, start, end);
    }
}

void update(int node, int start, int end, int l, int r, int value) {
    if (start > end || start > r || end < l) return;
    if (start == end) {
        tree[node] = {value, value, value, value};
    } else {
        int mid = (start + end) / 2;
        update(2 * node, start, mid, l, r, value);
        update(2 * node + 1, mid + 1, end, l, r, value);
        merge(node, start, end);
    }
}

void occupy(int l, int r) {
    update(1, 0, n - 1, l, r, 0);
}

void free(int l, int r) {
    update(1, 0, n - 1, l, r, 1);
}

int getMaxFreeSegment() {
    return tree[1].max_free;
}

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

    tree.resize(4 * n);
    build(1, 0, n - 1);
    vector<int> results;

    for (int p = 0; p < P; ++p) {
        int c;
        cin >> c;
        if (c == 1) {
            int i, M;
            cin >> i >> M;
            occupy(i - 1, i + M - 2);
        } else if (c == 2) {
            int i, M;
            cin >> i >> M;
            free(i - 1, i + M - 2);
        } else if (c == 3) {
            results.push_back(getMaxFreeSegment());
        }
    }

    for (int res : results) {
        cout << res << endl;
    }

    return 0;
}