Cod sursa(job #3154255)

Utilizator StefanL2005Stefan Leustean StefanL2005 Data 3 octombrie 2023 21:37:03
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>
#include <algorithm>
using namespace std;
ifstream in("hotel.in");
ofstream out("hotel.out");

struct seq{
    int dp, st, m;
    int carry = -1; // 0 daca umplem camerele 1 daca le eliberam, -1 daca nimic
};

void merge_cells(int node, vector<seq> &tree, int l, int r, int mij)
{
    if (tree[2*node].st == mij - l + 1)
        tree[node].st = tree[2*node].st + tree[2*node + 1].st;
    else
        tree[node].st = tree[2*node].st;

    if (tree[2*node + 1].dp == r - mij)
        tree[node].dp = tree[2*node + 1].dp + tree[2*node].dp;
    else
        tree[node].dp = tree[2*node + 1].dp;

    tree[node].m = max(tree[2*node].m, max(tree[2*node + 1].m, tree[2*node].dp + tree[2*node + 1].st));
}

void fill_cell(int node, vector<seq> &tree, int a, int c)
{
    tree[node].dp = a; tree[node].st = a; tree[node].m = a;
    tree[node].carry = c;
}

void init(int node, int l, int r, vector<seq> &tree)
{
    if (l == r)
    {
        fill_cell(node, tree, 1, -2);
        return;
    }
    
    int mij = (l + r) / 2;

    init(2*node, l, mij, tree);
    init(2*node + 1, mij + 1, r, tree);

    merge_cells(node, tree, l, r, mij);
}

void room_oper(int type, int node, int l, int r, int ql, int qr, vector<seq> &tree)
{
    if (ql <= l && r <= qr)
    {
        switch(type)
        {
            case 1:{
                fill_cell(node, tree, 0, 0);
            break;}
            case 2:{
                fill_cell(node, tree, r - l + 1, 1);
            break;}
        }
        return;
    }
    
    int mij = (l + r) / 2;

    switch(tree[node].carry)
    {
        case -1:{break;}

        case 0:{
            fill_cell(2*node, tree, 0, 0);
            fill_cell(2*node + 1, tree, 0, 0);
            tree[node].carry = -1;
        break;}

        case 1:{
            fill_cell(2*node, tree, mij - l + 1, 1);
            fill_cell(2*node + 1, tree, r - mij, 1);
            tree[node].carry = -1;
        break;}
    }
        
    if (ql <= mij)
        room_oper(type, 2*node, l, mij, ql, qr, tree);
    if (mij + 1 <= qr)
        room_oper(type, 2*node + 1, mij + 1, r, ql, qr, tree);

    merge_cells(node, tree, l, r, mij);
}

int main()
{
    int n, Q;
    in>> n >> Q;
    vector<seq> tree(4 * n);
    init(1, 0, n - 1, tree);

    for (int question = 0; question < Q; question++)
    {
        int type;
        in>> type;

        if (type == 3)
        {
            out<< tree[1].m << "\n";
            continue;
        }
        int a, b;
        in>> a >> b;

        room_oper(type, 1, 0, n - 1, a - 1, a + b - 2, tree);
    }
    return 0;
}