Cod sursa(job #3161620)

Utilizator dragoncrackCandidatu Mario Luca dragoncrack Data 27 octombrie 2023 17:50:09
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.55 kb
#include <fstream>
#include <vector>
#define DIM 100001

using namespace std;

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

struct node {
    bool occupied;
    bool wasUpdated;
};

int n, m;
node AINT[4 * DIM];

void delayedUpdate(int nod) {
    AINT[nod].wasUpdated = false;

    AINT[2 * nod].occupied = AINT[nod].occupied;
    AINT[2 * nod + 1].occupied = AINT[nod].occupied;

    AINT[2 * nod].wasUpdated = true;
    AINT[2 * nod + 1].wasUpdated = true;
}

void update(int nod, int st, int dr, int a, int b, bool value) {
    if (a <= st && dr <= b) {
        AINT[nod].occupied = value;
        AINT[nod].wasUpdated = true;
    }
    else {
        int mid = (st + dr) / 2;
        
        if (AINT[nod].wasUpdated)
            delayedUpdate(nod);

        if (a <= mid)
            update(2 * nod, st, mid, a, b, value);
        if (b > mid)
            update(2 * nod + 1, mid + 1, dr, a, b, value);

        AINT[nod].occupied = AINT[2 * nod].occupied && AINT[2 * nod + 1].occupied;
    }
}

void printAINT(int nod, int st, int dr) {
    if (AINT[nod].wasUpdated) {
        for (int i = st; i <= dr; i++) {
            fout << AINT[nod].occupied;
        }
    }
    else {
        int mid = (st + dr) / 2;
        printAINT(2 * nod, st, mid);
        printAINT(2 * nod + 1, mid + 1, dr);
    }
}

vector<pair<int, int>> getIntervals(int nod, int st, int dr) {
    if (AINT[nod].occupied) {
        return vector<pair<int, int>>({ make_pair(st, dr) });
    }
    else if (AINT[nod].wasUpdated) {
        return vector<pair<int, int>>();
    }
    else {
        int mid = (st + dr) / 2;
        vector<pair<int, int>> child1 = getIntervals(2 * nod, st, mid);
        vector<pair<int, int>> child2 = getIntervals(2 * nod + 1, mid + 1, dr);

        // make the intesection a single interval if possible
        if (child1.size() > 0 && child2.size() > 0) {
            if (child1[child1.size() - 1].second == child2[0].first - 1) {
                child2[0].first = child1[child1.size() - 1].first;
                child1.pop_back();
            }
        }

        // make result
        child1.insert(child1.end(), child2.begin(), child2.end());

        // return result
        return child1;
    }
}

int currentNode;

int main()
{
    fin >> n;
    fin >> m;
    AINT[1].wasUpdated = true;
    for (int i = 1; i <= m; i++) {
        int op, a, b;
        fin >> op;
        if (op == 1) {
            fin >> a >> b;
            update(1, 1, n, a, a + b - 1, true);
        }
        if (op == 2) {
            fin >> a >> b;
            update(1, 1, n, a, a + b - 1, false);
        }
        if (op == 3) {
            vector<pair<int, int>> currentOccupiedIntervals = getIntervals(1, 1, n);
            int maxim = 0;
            if (currentOccupiedIntervals.size() == 0) {
                maxim = n;
            }
            else {
                for (int j = 0; j < currentOccupiedIntervals.size(); j++) {
                    if (j == 0) {
                        maxim = max(maxim, currentOccupiedIntervals[j].first - 1);
                    }
                    else {
                        maxim = max(maxim, currentOccupiedIntervals[j].first - currentOccupiedIntervals[j - 1].second - 1);
                    }
                    if (j == currentOccupiedIntervals.size() - 1) {
                        maxim = max(maxim, n - currentOccupiedIntervals[j].second);
                    }
                }
            }
            fout << maxim << "\n";
        }
    }
}