Cod sursa(job #2954678)

Utilizator Razvan48Capatina Razvan Nicolae Razvan48 Data 14 decembrie 2022 23:45:59
Problema Hotel Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.72 kb
#include <fstream>

using namespace std;

const int NMAX = 100000;

int lazy[1 + 4 * NMAX];

int sumSt[1 + 4 * NMAX];
int sumDr[1 + 4 * NMAX];
int sumMij[1 + 4 * NMAX];

void applyLazyFiu(int index, int st, int dr)
{
    if (lazy[index] == 0)
        return;

    if (lazy[index] == -1) ///Update in 0
    {
        sumSt[index] = 0;
        sumDr[index] = 0;
        sumMij[index] = 0;
    }
    else if (lazy[index] == 1) ///Update in 1
    {
        sumSt[index] = dr - st + 1;
        sumDr[index] = dr - st + 1;
        sumMij[index] = dr - st + 1;
    }

    if (st < dr)
    {
        int fiuSt = 2 * index;
        int fiuDr = 2 * index + 1;

        lazy[fiuSt] = lazy[index];
        lazy[fiuDr] = lazy[index];
    }

    lazy[index] = 0;
}

void applyLazy(int index, int st, int dr)
{
    if (lazy[index] == 0)
        return;

    if (lazy[index] == -1) ///Update in 0
    {
        sumSt[index] = 0;
        sumDr[index] = 0;
        sumMij[index] = 0;
    }
    else if (lazy[index] == 1) ///Update in 1
    {
        sumSt[index] = dr - st + 1;
        sumDr[index] = dr - st + 1;
        sumMij[index] = dr - st + 1;
    }

    if (st < dr)
    {
        int mij = (st + dr) / 2;

        int fiuSt = 2 * index;
        int fiuDr = 2 * index + 1;

        lazy[fiuSt] = lazy[index];
        lazy[fiuDr] = lazy[index];

        applyLazyFiu(fiuSt, st, mij);
        applyLazyFiu(fiuDr, mij + 1, dr);
    }

    lazy[index] = 0;
}

void updateAint(int index, int st, int dr, int stUp, int drUp, int val)
{
    applyLazy(index, st, dr);

    if (st == stUp && dr == drUp)
    {
        lazy[index] = val;

        return;
    }

    int mij = (st + dr) / 2;

    int fiuSt = 2 * index;
    int fiuDr = 2 * index + 1;

    if (drUp <= mij)
        updateAint(fiuSt, st, mij, stUp, drUp, val);
    else if (stUp >= mij + 1)
        updateAint(fiuDr, mij + 1, dr, stUp, drUp, val);
    else
    {
        updateAint(fiuSt, st, mij, stUp, mij, val);
        updateAint(fiuDr, mij + 1, dr, mij + 1, drUp, val);
    }

    int sumSt1 = sumSt[fiuSt];
    int sumSt2 = sumSt[fiuDr];
    int sumDr1 = sumDr[fiuSt];
    int sumDr2 = sumDr[fiuDr];
    int sumMij1 = sumMij[fiuSt];
    int sumMij2 = sumMij[fiuDr];

    if (lazy[fiuSt] == -1)
    {
        sumSt1 = 0;
        sumDr1 = 0;
        sumMij1 = 0;
    }
    else if (lazy[fiuSt] == 1)
    {
        sumSt1 = 1;
        sumDr1 = 1;
        sumMij1 = 1;
    }

    if (lazy[fiuDr] == -1)
    {
        sumSt2 = 0;
        sumDr2 = 0;
        sumMij2 = 0;
    }
    else if (lazy[fiuDr] == 1)
    {
        sumSt2 = 1;
        sumDr2 = 1;
        sumMij2 = 1;
    }

    if (sumSt1 == mij - st + 1)
        sumSt[index] = sumSt1 + sumSt2; ///sumSt[fiuSt] == sumaTotala[fiuSt] in acest caz
    else
        sumSt[index] = sumSt1;

    if (sumDr2 == dr - (mij + 1) + 1)
        sumDr[index] = sumDr2 + sumDr1; ///sumDr[fiuDr] == sumaTotala[fiuDr] aici
    else
        sumDr[index] = sumDr2;

    sumMij[index] = max(max(sumMij1, sumMij2), sumDr1 + sumSt2);
}

int sol;
int solDr;

void queryAint(int index, int st, int dr, int stQ, int drQ)
{
    applyLazy(index, st, dr);

    if (st == stQ && dr == drQ)
    {
        sol = max(sol, solDr + sumSt[index]);
        sol = max(sol, sumDr[index]);
        sol = max(sol, sumMij[index]);

        if (sumDr[index] == dr - st + 1) ///sumDr[index] == sumaTotala[index] aici
            solDr = solDr + sumDr[index];
        else
            solDr = sumDr[index];

        return;
    }

    int mij = (st + dr) / 2;

    int fiuSt = 2 * index;
    int fiuDr = 2 * index + 1;

    if (drQ <= mij)
        queryAint(fiuSt, st, mij, stQ, drQ);
    else if (stQ >= mij + 1)
        queryAint(fiuDr, mij + 1, dr, stQ, drQ);
    else
    {
        queryAint(fiuSt, st, mij, stQ, mij);
        queryAint(fiuDr, mij + 1, dr, mij + 1, drQ);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);

    ifstream in("hotel.in");
    ofstream out("hotel.out");

    int n, p;
    in >> n >> p;

    updateAint(1, 1, n, 1, n, 1);

    for (int j = 1; j <= p; j++)
    {
        int tip;
        in >> tip;

        if (tip == 1)
        {
            int i, m;
            in >> i >> m;

            updateAint(1, 1, n, i, i + m - 1, -1);
        }
        else if (tip == 2)
        {
            int i, m;
            in >> i >> m;

            updateAint(1, 1, n, i, i + m - 1, 1);
        }
        else
        {
            sol = 0;
            solDr = 0;

            queryAint(1, 1, n, 1, n);

            out << sol << '\n';
        }
    }

    in.close();
    out.close();

    return 0;
}