Pagini recente » Cod sursa (job #245365) | Cod sursa (job #3264442) | Cod sursa (job #2152294) | Cod sursa (job #1686119) | Cod sursa (job #3134692)
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
ifstream f("hotel.in");
ofstream g("hotel.out");
struct node // structura unui nod din arbore
{
int st, dr, total;
};
const int N = 100005;
int n, q; // n = numarul de camere, q = numarul de operatii
node arb[4 * N]; // arborele
int hotel[4 * N];
int max(int a, int b, int c) // functie care returneaza maximul dintre 3 numere
{
return max(max(a, b), c);
}
void updateNode(int ti, int tl, int tr) // functia face update la nodul cu indexul ti
{
arb[ti].total = max(arb[ti * 2].total, arb[ti * 2 + 1].total, arb[ti * 2].dr + arb[ti * 2 + 1].st); // actualizez valoarea totala
int mid = (tl + tr) / 2; // mijlocul intervalului
arb[ti].st = arb[ti * 2].st; // actualizez valoarea stanga
if (arb[ti].st == mid - tl + 1) // daca valoarea stanga este egala cu lungimea intervalului
{
arb[ti].st += arb[ti * 2 + 1].st; // actualizez valoarea stanga
}
arb[ti].dr = arb[ti * 2 + 1].dr; // actualizez valoarea dreapta
if (arb[ti].dr == tr - mid) // daca valoarea dreapta este egala cu lungimea intervalului
{
arb[ti].dr += arb[ti * 2].dr; // actualizez valoarea dreapta
}
}
void build(int tl = 1, int tr = n, int ti = 1) // functia construieste arborele
{
if (tl == tr) // daca am ajuns la o frunza
{
arb[ti].dr = arb[ti].st = arb[ti].total = 1; // initializam valorile
return;
}
int mid = (tl + tr) / 2; // mijlocul intervalului
build(tl, mid, ti * 2); // construim subarborele stang
build(mid + 1, tr, ti * 2 + 1); // construim subarborele drept
updateNode(ti, tl, tr); // actualizam nodul
}
void update(int qt, int ql, int qr, int tl = 1, int tr = n, int ti = 1)
{
// 1 = ocupa camere
// 2 = elibereaza camere
int lungime = tr - tl + 1; // lungimea intervalului
if (hotel[ti]) // daca nodul este marcat
{
if (hotel[ti] == 1) // daca nodul este marcat cu 1
{
arb[ti].dr = arb[ti].st = arb[ti].total = 0; // dreapta, stanga si totalul devin 0
}
else
{
arb[ti].dr = arb[ti].st = arb[ti].total = lungime; // dreapta, stanga si totalul devin lungimea intervalului
}
if (tl < tr) // daca nu am ajuns la o frunza
{
hotel[ti * 2] = hotel[ti * 2 + 1] = hotel[ti];
}
hotel[ti] = 0;
}
// not included
if (tr < ql || qr < tl) // daca intervalul nu este inclus in intervalul dat
{
return;
}
// fully included
if (ql <= tl && tr <= qr) // daca intervalul este inclus in intervalul dat
{
if (qt == 1)
{
arb[ti].dr = arb[ti].st = arb[ti].total = 0;
}
else
{
arb[ti].dr = arb[ti].st = arb[ti].total = lungime;
}
if (tl < tr)
{
hotel[ti * 2] = hotel[ti * 2 + 1] = qt;
}
return;
}
// partial included
int mid = (tl + tr) / 2;
update(qt, ql, qr, tl, mid, ti * 2);
update(qt, ql, qr, mid + 1, tr, ti * 2 + 1);
updateNode(ti, tl, tr);
}
int main()
{
f >> n >> q;
build();
while (q--) // cat timp mai am operatii de facut
{
int c;
f >> c;
if (c == 3) // daca cererea este de tipul 3
{
g << arb[1].total << '\n';
}
else
{
int l, nr;
f >> l >> nr;
int r = l + nr - 1;
update(c, l, r);
}
}
}