Cod sursa(job #2141715)

Utilizator AlexandruLuchianov1Alex Luchianov AlexandruLuchianov1 Data 24 februarie 2018 15:51:05
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.66 kb
#include <iostream>
#include <fstream>

using namespace std;

ifstream in ("hotel.in");
ofstream out ("hotel.out");

int const nmax = 100000;

struct Node {
  //campuri
  int sol; //nr maxim de camere libere consecutive
  int dr;  //nr maxim de camere libere consecutive incepand din extrema dreapta
  int st;  //nr maxim de camere libere consecutive incepand din extrema stanga

  //campuri de update lazy
  bool empty;
  //daca empty == true, toate camere sunt libere, empty == false nu inseamna nimic
  bool full;
  //daca full == true, toate camere sunt pline, empty == false nu inseamna nimic

  void initempty(int node, int from, int to) {
    sol = to - from + 1;
    dr = sol;
    st = sol;
    empty = 1;
    full = 0;
  }

  void initfull(int node, int from, int to) {
    sol = 0;
    dr = 0;
    st = 0;
    empty = 0;
    full = 1;
  }
};
Node arb[5 + nmax * 4];

//nodul e clean
//nodul nu e frunza
//fii nodului sunt clean (astea sunt presupunrile tale aici)
//DECI ai grija sa cureti si fiii in cleannode!
void computenode(int node , int from, int to) {
  Node &a = arb[2 * node];
  Node &b = arb[2 * node + 1];

  arb[node].sol = max(max(a.sol , b.sol), a.dr + b.st);
  if(b.empty)
    arb[node].dr = a.dr + b.dr;
  else
    arb[node].dr = b.dr;

  if(a.empty)
    arb[node].st = a.st + b.st;
  else
    arb[node].st = a.st;

  arb[node].empty = a.empty & b.empty;
  arb[node].full = a.full & b.full;
}

void buildtree(int node, int from, int to) {
  if(from == to) {
    arb[node].initempty(node, from, to);
  } else {
    int mid = (from + to) / 2;
    buildtree(node * 2, from, mid);
    buildtree(node * 2 + 1, mid + 1 , to);
    computenode(node, from, to);
  }
}

//tu consideri ca node e clean si de fapt ii cureti fiii
void cleannode(int node , int from , int to) {
  if(from < to) {
    int mid = (from + to) / 2;
    if(arb[node].empty == 1) {
      arb[node * 2].initempty(node * 2 , from , mid);
      arb[node * 2 + 1].initempty(node * 2 + 1 , mid + 1, to);
    } else if(arb[node].full == 1){
      arb[node * 2].initfull(node * 2 , from , mid);
      arb[node * 2 + 1].initfull(node * 2 + 1 , mid + 1, to);
    }
  }
}

void update(int node ,int from , int to , int x , int y , bool fill) {
  if(from == x && to == y){
    if(fill == 1)
      arb[node].initfull(node , from , to);  //initializare harnica
    else
      arb[node].initempty(node , from , to);
    //cleannode(node, from, to);
    //tu cand mergi de sus in jos si vezi primul nod empty sau full, tu trebuie sa stii ca ai sub el doi fii curati
  } else {
    cleannode(node, from, to);
    int mid = (from + to) / 2;
    if(x <= mid)
      update(node * 2, from, mid, x, min(mid, y), fill);
    if(mid + 1 <= y)
      update(node * 2 + 1 , mid + 1 , to , max(mid + 1 , x) , y , fill);
    computenode(node , from , to);
  }
}
void printtree(int node , int from , int to){
  cout<<node<<" "<<from<<" "<<to<<" "<<arb[node].st<<" "<<arb[node].dr<<" "<<arb[node].full<<" "<<arb[node].empty<<'\n';
  if(from < to){
    int mid = (from + to) / 2;
    printtree(node * 2 , from ,mid);
    printtree(node * 2 + 1 , mid + 1 , to);
  }
}
int main(){
  int n, m;
  in >> n >> m;
  buildtree(1 , 1 , n);
  //printtree(1 , 1 , n);
  //cout<<'\n';
  for(int i = 1 ; i <= m ;i++){
    int p;
    in>>p;
    if(p == 1){
      int x , y;
      in>>x>>y;
      y = x + y - 1;
      update(1 , 1 , n , x , y , 1);
    } else if(p == 2){
      int x , y;
      in>>x>>y;
      y = x + y - 1;
      update(1 , 1 , n , x , y , 0);
    } else{
      out<<arb[1].sol<<'\n';
    }
    //printtree(1 , 1 , n);
    //cout<<'\n';
  }
}