Cod sursa(job #3233164)

Utilizator AndreiDocaDoca Andrei AndreiDoca Data 2 iunie 2024 18:01:34
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.18 kb
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;

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

vector<Node> tree;
vector<int> lazy;
int n;

void apply_lazy(int node, int start, int end) {
    if (lazy[node] != -1) {
        int value = lazy[node];
        tree[node] = {value * (end - start + 1), value * (end - start + 1), value * (end - start + 1), value * (end - start + 1)};
        if (start != end) {
            lazy[2 * node] = value;
            lazy[2 * node + 1] = value;
        }
        lazy[node] = -1;
    }
}

void merge(int node, int start, int end) {
    int mid = (start + end) / 2;
    int left_child = 2 * node;
    int right_child = 2 * node + 1;
    
    apply_lazy(left_child, start, mid);
    apply_lazy(right_child, mid + 1, end);
    
    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) {
    apply_lazy(node, start, end);
    if (start > end || start > r || end < l) return;
    if (start >= l && end <= r) {
        lazy[node] = value;
        apply_lazy(node, start, end);
    } 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() {
    apply_lazy(1, 0, n - 1);
    return tree[1].max_free;
}

int main() {
    ifstream fin("hotel.in");
    ofstream fout("hotel.out");
    int P;
    fin >> n >> P;

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

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

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

    fin.close();
    fout.close();

    return 0;
}