Cod sursa(job #3304178)

Utilizator EricDimiCismaru Eric-Dimitrie EricDimi Data 21 iulie 2025 14:54:11
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.49 kb
#include <bits/stdc++.h>

std::ifstream fin("hotel.in");
std::ofstream fout("hotel.out");

const int MAX_N = 100'000;

struct Node {
    int pref_max; /// cel mai lung prefix cu elemente de 0
    int suff_max; /// cel mai lung sufix cu elemente de 0
    int len_max;  /// secventa de lungime maxima cu 0
    int lazy;     /// 0, daca operatia a fost trimisa fiilor nodului, 1, daca se ocupa camerele, 2, daca se elibereaza
};

Node segment_tree[MAX_N << 2 | 1];
int n, p, t, i, m;

void update_node(int node, int left, int right) {
    int mid = (left + right) >> 1;
    /// [left, mid] -> mid - left + 1 elemente
    /// [mid + 1, right] -> right - mid elemente
    segment_tree[node].pref_max = (segment_tree[node << 1].pref_max == mid - left + 1) ? segment_tree[node << 1].pref_max + segment_tree[node << 1 | 1].pref_max : segment_tree[node << 1].pref_max;
    segment_tree[node].suff_max = (segment_tree[node << 1 | 1].suff_max == right - mid) ? segment_tree[node << 1].suff_max + segment_tree[node << 1 | 1].suff_max : segment_tree[node << 1 | 1].suff_max;
    segment_tree[node].len_max = std::max({segment_tree[node << 1].len_max, segment_tree[node << 1 | 1].len_max, segment_tree[node << 1].suff_max + segment_tree[node << 1 | 1].pref_max});
}

void propagate(int node, int left, int right) {
    if (segment_tree[node].lazy > 0) {
        if (segment_tree[node].lazy == 1) {
            /// avem interogare pentru a se ocupa camerele (se umple secventa cu 1)
            segment_tree[node].pref_max = 0;
            segment_tree[node].suff_max = 0;
            segment_tree[node].len_max = 0;
            if (left != right) { /// nodul nu este frunza
                segment_tree[node << 1].lazy = segment_tree[node].lazy;
                segment_tree[node << 1 | 1].lazy = segment_tree[node].lazy;
            }
        } else 
        if (segment_tree[node].lazy == 2) {
            /// avem interogare pentru a se elibera camerele (se umple cu 0 secventa)
            segment_tree[node].pref_max = right - left + 1;
            segment_tree[node].suff_max = right - left + 1;
            segment_tree[node].len_max = right - left + 1;
            if (left != right) {
                segment_tree[node << 1].lazy = segment_tree[node].lazy;
                segment_tree[node << 1 | 1].lazy = segment_tree[node].lazy;         
            }
        }
        segment_tree[node].lazy = 0;
    }
}

void update(int node, int left, int right, int q_left, int q_right, int task) {
    if (q_left <= left && right <= q_right) {
        segment_tree[node].lazy = task;
        return;
    }
    propagate(node, left, right);
    int mid = (left + right) >> 1;
    if (q_left <= mid)
        update(node << 1, left, mid, q_left, q_right, task);
    if (q_right > mid)
        update(node << 1 | 1, mid + 1, right, q_left, q_right, task);
    propagate(node << 1, left, mid);
    propagate(node << 1 | 1, mid + 1, right);
    update_node(node, left, right);
}

int main() {
    fin >> n >> p;
    update(1, 1, n, 1, n, 2); /// starea initiala: 0, 0, ..., 0
    while (p--) {
        fin >> t;
        if (t == 1) {
            fin >> i >> m;
            update(1, 1, n, i, i + m - 1, 1);
        } else 
        if (t == 2) {
            fin >> i >> m;
            update(1, 1, n, i, i + m - 1, 2);
        } else {
            propagate(1, 1, n);
            fout << segment_tree[1].len_max << "\n";
        }
    }
    
    fin.close();
    fout.close();
    
    return 0;
}