Cod sursa(job #1998005)

Utilizator Mihai_PredaPreda Mihai Dragos Mihai_Preda Data 6 iulie 2017 10:49:30
Problema Hotel Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.04 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

struct nod
{
    int toUpdate; // 0 -> nu avem update
                  //-1 -> tot nodul il facem maxim
                  // 1 -> tot nodul il facem 0
    int ssSt, ssDr, ssMid;
};

class aint
{
public:
    aint(int n)
    {
        this->n = n;
        v = vector<nod>((1 << (int)ceil(log2(2*n))) + 1, nod());
        Build(1, 1, n);
    }
    inline void Update(int start, int finish, int val)
    {
        Update(start, finish, val, 1, 1, n);
    }
    int Query()
    {
        return v[1].ssMid;
    }
private:
    void Build(int cNod, int cSt, int cDr)
    {
        v[cNod].ssSt = v[cNod].ssDr = v[cNod].ssMid = cDr - cSt + 1;
        if(cSt == cDr)
            return;
        int mid = (cSt + cDr) / 2;
        int fiuSt = 2 * cNod, fiuDr = 2 * cNod + 1;
        Build(fiuSt, cSt, mid);
        Build(fiuDr, mid + 1, cDr);
    }
    inline void UpdateNod(int cNod, int nodSz)
    {
        if(v[cNod].toUpdate == 0)
            return;
        if(nodSz > 1)
        {
            v[cNod*2].toUpdate = v[cNod].toUpdate;
            v[cNod*2+1].toUpdate = v[cNod].toUpdate;
        }
        if(v[cNod].toUpdate == -1)
            v[cNod].ssSt = v[cNod].ssDr = v[cNod].ssMid = nodSz;
        else
            v[cNod].ssSt = v[cNod].ssDr = v[cNod].ssMid = 0;
        v[cNod].toUpdate = 0;
    }
    void Update(int start, int finish, int val, int cNod, int cSt, int cDr)
    {
        if(start <= cSt && cDr <= finish)
        {
            v[cNod].toUpdate = val;
            return;
        }
        UpdateNod(cNod, cDr - cSt + 1);
        int mid = (cSt + cDr) / 2;
        int fiuSt = 2 * cNod, fiuDr = 2 * cNod + 1;
        if(start <= mid)
            Update(start, finish, val, fiuSt, cSt, mid);
        if(finish > mid)
            Update(start, finish, val, fiuDr, mid + 1, cDr);
        UpdateNod(fiuSt, mid - cSt + 1);
        UpdateNod(fiuDr, cDr - mid);
        v[cNod] = comb(v[fiuSt], v[fiuDr], mid - cSt + 1, cDr - mid);
    }
    inline nod comb(const nod &st, const nod &dr, int stSize, int drSize) const
    {
        nod ret;
        ret.ssSt = max(st.ssSt, st.ssMid == stSize ? st.ssMid + dr.ssSt : 0);
        ret.ssMid = max(st.ssDr + dr.ssSt, max(st.ssMid, dr.ssMid));
        ret.ssDr = max(dr.ssDr, dr.ssMid == drSize ? st.ssDr + dr.ssMid : 0);
        return ret;
    }
    int n;
    vector<nod> v;
};

int main()
{
    int n, p;
    ifstream in("hotel.in");
    ofstream out("hotel.out");
    in >> n >> p;
    aint aint(n);
    int c, start, lg;
    for(int i = 1; i <= p; ++i)
    {
        in >> c;
        if(c == 1)
        {
            in >> start >> lg;
            aint.Update(start, start + lg - 1, 1);
        }
        else if(c == 2)
        {
            in >> start >> lg;
            aint.Update(start, start + lg - 1, -1);
        }
        else
            out << aint.Query() << "\n";
    }
    in.close();
    out.close();
    return 0;
}