Pagini recente » Cod sursa (job #2011853) | Cod sursa (job #1114096) | ONIS 2014, Runda 2 | Istoria paginii preoni-2004/runda-1 | Cod sursa (job #2007940)
#include <iostream>
#include <fstream>
#define ll long long
#define pb push_back
using namespace std;
ifstream in("hotel.in");
ofstream out("hotel.out");
const int NMax = 1e5 + 5;
const int arbMax = 262144 + 5;
int N,M;
short lazy[arbMax];
// lazy[i] = 1 daca este necesar un update de ocupare pe nodul cu indexul node
// lazy[i] = -1 daca este necesar un update de golire pe nodul cu indexul node
// lazy[i] = 0 daca nu este necesar un update
struct elem {
int free = 0,st = 0,dr = 0;
}arb[arbMax];
// arb[i].free = numarul maxim de camere consecutive libere din intervalul curent;
// arb[i].st = numarul de camere consecutive libere pornind de la stanga intervalului;
// arb[i].st = numarul de camere consecutive libere pornind de la dreapta intervalului;
void update(int,int,int,int,int,bool);
int main() {
in>>N>>M;
update(1,1,N,1,N,true);
// se face un update care elibereaza toate camerele;
while (M--) {
int tip,a,b;
in>>tip;
if (tip == 3) {
out<<arb[1].free<<'\n';
}
else {
in>>a>>b;
b = a+b-1;
if (tip == 1) {
update(1,1,N,a,b,false);
}
else {
update(1,1,N,a,b,true);
}
}
}
in.close();out.close();
return 0;
}
// node - indexul nodului curent
// [st;dr] - intervalul retinut de nodul curent
// [a;b] - intervalul pe care se face update
// golire = true daca se elibereaza camere
// golire = false daca se ocupa camere
void update(int node,int st,int dr,int a,int b,bool golire) {
int fs = node<<1, ss = fs+1;
// se face lazy update-ul ramas pe acest nod
if (lazy[node] != 0) {
if (lazy[node] == 1) {
arb[node].free = arb[node].st = arb[node].dr = 0;
}
else if (lazy[node] == -1) {
arb[node].free = arb[node].st = arb[node].dr = (dr-st+1);
}
if (st != dr) {
lazy[fs] = lazy[node];
lazy[ss] = lazy[node];
}
lazy[node] = 0;
}
// daca intervalele nu au elemente comune, se iese din functie;
// se poate ajunge in acest caz deoarece
// mai jos se apeleaza ambele update-uri intotdeauna;
// acest lucru este necesar pentru a face lazy update-urile necesare
// pe fii inainte de a modifica valoarea din acest nod;
if (b < st || dr < a) {
return;
}
if (a <= st && dr <= b) {
if (golire) {
arb[node].free = arb[node].st = arb[node].dr = (dr-st+1);
if (st != dr) {
lazy[fs] = -1;
lazy[ss] = -1;
}
}
else {
arb[node].free = arb[node].st = arb[node].dr = 0;
if (st != dr) {
lazy[fs] = 1;
lazy[ss] = 1;
}
}
return;
}
int mij = (st+dr)>>1;
update(fs,st,mij,a,b,golire);
update(ss,mij+1,dr,a,b,golire);
// daca fiul stang are toate camerele libere, atunci cele din stanga se pot continua cu arb[ss].st;
arb[node].st = arb[fs].st + ((arb[fs].free == mij-st+1) ? arb[ss].st : 0);
// daca fiul drept are toate camerele libere, atunci cele din dreapta se pot continua cu arb[fs].dr;
arb[node].dr = arb[ss].dr + ((arb[ss].free == dr-(mij+1)+1) ? arb[fs].dr : 0);
arb[node].free = max(arb[fs].dr + arb[ss].st,max(arb[fs].free,arb[ss].free));
}