Cod sursa(job #3327535)

Utilizator mirceamaierean41Mircea Maierean mirceamaierean41 Data 4 decembrie 2025 13:14:09
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;

ifstream fin{"hotel.in"};
ofstream fout{"hotel.out"};

const int NMAX = 1e5 + 1;

struct ST
{
    int lazy, leftSum, rightSum, maxSum;
    ST() : leftSum{1}, rightSum{1}, maxSum{1}, lazy{-1} {};
};

ST st[4 * NMAX];

void setVal(ST &node, int leftSum, int rightSum, int maxSum)
{
    node.leftSum = leftSum;
    node.rightSum = rightSum;
    node.maxSum = maxSum;
}

void merge(ST &node, ST &left, ST &right, bool emptyLeft, bool emptyRight)
{
    node.leftSum = left.leftSum;
    node.rightSum = right.rightSum;

    if (emptyLeft)
        node.leftSum += right.leftSum;

    if (emptyRight)
        node.rightSum += left.rightSum;

    node.maxSum = max({left.maxSum, right.maxSum, left.rightSum + right.leftSum});
}

void update(int crtIndex, int left, int right, int &queryLeft, int &queryRight, int &queryType)
{
    if (st[crtIndex].lazy != -1)
    {
        if (st[crtIndex].lazy == 1)
            setVal(st[crtIndex], 0, 0, 0);
        else
            setVal(st[crtIndex], right - left + 1, right - left + 1, right - left + 1);

        if (left < right)
            st[2 * crtIndex].lazy = st[2 * crtIndex + 1].lazy = st[crtIndex].lazy;

        st[crtIndex].lazy = -1;
    }

    if (left > queryRight || right < queryLeft)
        return;

    if (queryLeft <= left && right <= queryRight)
    {
        if (queryType == 1)
            setVal(st[crtIndex], 0, 0, 0);

        else
            setVal(st[crtIndex], right - left + 1, right - left + 1, right - left + 1);

        if (left != right)
            st[2 * crtIndex].lazy = st[2 * crtIndex + 1].lazy = queryType;

        return;
    }

    int m = (left + right) / 2;

    update(2 * crtIndex, left, m, queryLeft, queryRight, queryType);
    update(2 * crtIndex + 1, m + 1, right, queryLeft, queryRight, queryType);

    merge(st[crtIndex], st[2 * crtIndex], st[2 * crtIndex + 1], st[2 * crtIndex].maxSum == (m - left + 1), st[2 * crtIndex + 1].maxSum == (right - m));
}

void build(int crtIndex, int left, int right)
{
    if (left == right)
        return;
    int m{(left + right) / 2};

    build(2 * crtIndex, left, m);
    build(2 * crtIndex + 1, m + 1, right);

    merge(st[crtIndex], st[2 * crtIndex], st[2 * crtIndex + 1], true, true);
}

int main()
{
    int n, p, q, l, r;
    fin >> n >> p;
    build(1, 1, n);
    while (p--)
    {
        fin >> q;
        if (q == 3)
            fout << st[1].maxSum << '\n';
        else
        {
            fin >> l >> r;
            r += l - 1;
            update(1, 1, n, l, r, q);
        }
    }
    return 0;
}