Cod sursa(job #3363252)

Utilizator nicoleta_iancuIancu Nicoleta nicoleta_iancu Data 14 august 2026 16:28:08
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.55 kb

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
struct node {
    int liber;//daca tot intervalul st,dr e liber
    int pref;//nr maxim de locuri libere din prefix aka (st,....)
    int sufix;//nr maxim de locuri libere din prefix de la (....dr)
    int total;//nr maxim libere per total
    //liber=0=> toate sunt libere
    //liber=1=> toate sunt ocupate
    //liber=-1=> nu e determinat
    node() :liber(-1), pref(0), sufix(0), total(0) {};
    node(int val):liber(0), pref(val), sufix(val), total(val) {};
};
struct AINT {
    vector<node>aint;
    void combin(node& crt, node& st, node& dr) {
        crt.sufix = dr.sufix;
        if (dr.liber==0) {
            crt.sufix += st.sufix;
        }
        crt.pref = st.pref;
        if (st.liber==0) {
            crt.pref +=dr.pref;
        }
        if (st.liber == 1 && dr.liber == 1) {
            crt.liber = 1;
        }
        else if (st.liber == 0 && dr.liber == 0) {
            crt.liber = 0;
        }
        else {
            crt.liber = -1;
        }

        crt.total = max(dr.total, st.total);
        crt.total = max(crt.total, st.sufix+dr.pref);
    }
    void resizeAint(int& n) {
        int logCrt = log2(n);
        if ((1 << logCrt) == n) {
            logCrt++;
        }
        aint.resize(1 << (1 + logCrt)+1);
    }
    void updateInterval(int pozTree, int st, int dr,int stUpdate,int drUpdate,bool leave) {
        int mij = (st + dr) / 2;
        int leftChild = 2 * pozTree;
        int rightChild = 2 * pozTree + 1;
        if (st >= stUpdate && dr <= drUpdate) {
                if (leave) {
                    aint[pozTree].liber = 0;
                    aint[pozTree].pref = (dr - st + 1);
                    aint[pozTree].sufix = (dr - st + 1);
                    aint[pozTree].total = (dr - st + 1);
                }
                else {
                    aint[pozTree].liber = 1;
                    aint[pozTree].pref = 0;
                    aint[pozTree].sufix = 0;
                    aint[pozTree].total = 0;
                }
                return;
        }
        if (aint[pozTree].liber == 1) {//adaugam starile anterioare
            aint[leftChild].liber = 1;
            aint[leftChild].pref = 0;
            aint[leftChild].sufix = 0;
            aint[leftChild].total = 0;
            aint[rightChild].liber = 1;
            aint[rightChild].pref = 0;
            aint[rightChild].sufix = 0;
            aint[rightChild].total = 0;
        }
        if (aint[pozTree].liber == 0) {//adaugam starile anterioare
            aint[leftChild].liber = 0;
            aint[leftChild].pref = mij - st + 1;
            aint[leftChild].sufix = mij - st + 1;
            aint[leftChild].total = mij - st + 1;
            aint[rightChild].liber = 0;
            aint[rightChild].pref = (dr - mij);
            aint[rightChild].sufix = (dr - mij);
            aint[rightChild].total = (dr - mij);
        }
        
        if (stUpdate <= mij) {
            updateInterval(leftChild, st, mij, stUpdate, drUpdate, leave);
        }
        if (drUpdate > mij) {
            updateInterval(rightChild,mij+1,dr, stUpdate, drUpdate, leave);
        }
        combin(aint[pozTree], aint[leftChild], aint[rightChild]);
    }
    void buildAint(int pozTree, int st, int dr) {
        if (st == dr) {
            aint[pozTree].liber = 0;
            aint[pozTree].sufix = 1;
            aint[pozTree].pref = 1;
            aint[pozTree].total = 1;
            return;
        }
        int mij = (st + dr) / 2;
        int leftChild = 2 * pozTree;
        int rightChild = 2 * pozTree + 1;
        buildAint(leftChild, st, mij);
        buildAint(rightChild, mij+1, dr);
        combin(aint[pozTree], aint[leftChild], aint[rightChild]);
    }
};
int main()
{
    int n,q;
    fin >> n>>q;
    AINT crt;
    crt.resizeAint(n);
    crt.buildAint(1, 0, n - 1);
    int op, st, cnt;
    while (q)
    {
        fin >> op;
        switch (op)
        {
            case 1:
                fin >> st >> cnt;
                crt.updateInterval(1, 0, n - 1, st-1, st-2+cnt, 0);
                break;
            case 2:
                fin >> st >> cnt;
                crt.updateInterval(1, 0, n - 1, st - 1, st - 2 + cnt, 1);
                break;
            default:
                fout << crt.aint[1].total << "\n";
                break;
        }
        --q;
    }
    return 0;
}
//=^..^=