Cod sursa(job #3352750)

Utilizator TraianQTraianQ TraianQ Data 1 mai 2026 10:25:14
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <fstream>
#include <bits/stdc++.h>
#include <iostream>
#define N 100005
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
struct Segtree{
    bool propagate;
    int propWith;
    int pref, suff, best;
    int len;
}V[4 * N];

void build(int v, int l, int r) {
    if (l == r) {
        V[v].len = 1;
        V[v].pref = V[v].suff = V[v].best = 1;
        return;
    }
    int mij = (l + r) / 2;
    build(v * 2, l, mij);
    build(v * 2 + 1, mij + 1, r);
    V[v].len = V[v * 2].len + V[v * 2 + 1].len;
    V[v].pref = V[v].suff = V[v].best = V[v].len;
}

void apply(int v, int val) {
    V[v].propagate = true;
    V[v].propWith = val;

    if (val == 0) { // Clearing rooms (Freeing)
        V[v].pref = V[v].suff = V[v].best = V[v].len;
    } else { // Occupying rooms (Filling)
        V[v].pref = V[v].suff = V[v].best = 0;
    }
}

void propagate(int v) {
    if(V[v].propagate == false)
        return;

    apply(v * 2, V[v].propWith);
    apply(v * 2 +1, V[v].propWith);
    V[v].propagate = false;
}

void op(int v, int l, int r, int updateL, int updateR, int propType) {

    if(l > updateR || r < updateL)
        return;

    if(updateL <= l && r <= updateR) {
        apply(v, propType);
        return;
    }

    propagate(v);
    int mij = (l + r) / 2;
    int left = v * 2, right = v * 2 + 1;
    op(left, l, mij, updateL, updateR, propType);
    op(right, mij+1, r, updateL, updateR, propType);

    V[v].pref = V[left].pref;
    if (V[left].pref == V[left].len) {
            V[v].pref = V[left].len + V[right].pref;
        }

    V[v].suff = V[right].suff;
    if (V[right].suff == V[right].len) {
        V[v].suff = V[right].len + V[left].suff;
    }

    V[v].best = max({
        V[left].best,
        V[right].best,
        V[left].suff + V[right].pref
    });
}

Segtree query(int v, int l, int r, int updateL, int updateR) {
    if(l > updateR || r < updateL) {
        Segtree empty;
        empty.len = 0;
        empty.pref = empty.suff = empty.best = 0;
        empty.propagate = false;
        return empty;
    }
    if(updateL <= l && r <= updateR)
        return V[v];

    propagate(v);
    int mij = (l + r) / 2;
    int left = v * 2, right = v * 2 + 1;
    Segtree A = query(left, l, mij, updateL, updateR);
    Segtree B = query(right, mij+1, r, updateL, updateR);

    Segtree res;
    res.len = A.len + B.len;

    res.pref = A.pref;
    res.suff = B.suff;

    if(A.pref == A.len)
        res.pref = A.len + B.pref;

    if(B.suff == B.len)
        res.suff = B.len + A.suff;

    res.best = max(
        max(A.best, B.best),
        A.suff + B.pref);

    return res;
}
int main()
{
    int n, P, cer, a, b;
    fin>>n>>P;
    build(1, 1, n);
    for(int p = 1; p <= P; p++) {
        fin>>cer;
        if(cer!=3)
            fin>>a>>b;
        if(cer==1) {
            op(1, 1, n, a, a + b - 1, 1); // we fill
        }
        else if(cer==2) {
            op(1, 1, n, a, a + b - 1, 0); // we empty
        }
        else {
            fout<<query(1, 1, n, 1, n).best<<'\n';
        }
    }
    return 0;
}