Cod sursa(job #3223303)

Utilizator andu9andu nita andu9 Data 12 aprilie 2024 22:57:41
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <iostream>
#include <fstream>

const int nMax = 1e5 + 1;

struct Node {
    bool modified;
    int lenStart, lenFinish, longest;
};

Node aint[4 * nMax];

void Build(int node, int left, int right) {
    if (left == right) {
        aint[node] = Node{false, 1, 1, 1};
    } else {
        int middle = (left + right) >> 1;
        Build(2 * node, left, middle);
        Build(2 * node + 1, middle + 1, right);
        aint[node] = Node{false, right - left + 1, right - left + 1, right - left + 1};
    }
}

void Update(int node, int left, int right, int start, int finish, int op) {
    if (start <= left && right <= finish) {
        if (op == 1) {
            aint[node] = Node{true, 0, 0, 0};
        } else {
            aint[node] = Node{true, right - left + 1, right - left + 1, right - left + 1};
        }
    } else {
        int middle = (left + right) / 2;

        if (aint[node].modified) {
            if (aint[node].longest > 0) {
                aint[2 * node] = Node{true, middle - left + 1, middle - left + 1, middle - left + 1};
                aint[2 * node + 1] = Node{true, right - middle, right - middle, right - middle};
            } else {
                aint[2 * node] = Node{true, 0, 0, 0};
                aint[2 * node + 1] = Node{true, 0, 0, 0};
            }
            aint[node].modified = false;
        }

        if (start <= middle) {
            Update(2 * node, left, middle, start, finish, op);
        }
        if (middle < finish) {
            Update(2 * node + 1, middle + 1, right, start, finish, op);
        }

        aint[node].longest = std::max(std::max(aint[2 * node].longest, aint[2 * node + 1].longest), aint[2 * node].lenFinish + aint[2 * node + 1].lenStart);

        if (aint[2 * node].lenStart == middle - left + 1) {
            aint[node].lenStart = aint[2 * node].lenStart + aint[2 * node + 1].lenStart;
        } else {
            aint[node].lenStart = aint[2 * node].lenStart;
        }

        if (aint[2 * node + 1].lenFinish == right - middle) {
            aint[node].lenFinish = aint[2 * node + 1].lenFinish + aint[2 * node].lenFinish;
        } else {
            aint[node].lenFinish = aint[2 * node + 1].lenFinish;
        }
    }
}


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

    int n, q; fin >> n >> q; Build(1, 1, n);

    for (int i = 0; i < q; i += 1) {
        int op; fin >> op;
        if (op == 1 || op == 2) {
            int start, Size; fin >> start >> Size;
            Update(1, 1, n, start, start + Size - 1, op);
        } else {
            fout << aint[1].longest << '\n';
        }
    }

    fin.close(), fout.close();
    return 0;
}