Cod sursa(job #2139216)

Utilizator GoogalAbabei Daniel Googal Data 22 februarie 2018 11:25:25
Problema Hotel Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.42 kb
#include <iostream>
#include <fstream>

using namespace std;

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

const int NMAX = 1e5;

struct Room {
  int best;
  int mle;
  int mri;
  bool type1; ///1 - free    0 - full
  bool type2;
};

int n, p;
Room aint[1 + 4 * NMAX];

Room make_node(int le, int ri, int type) {
  /// type 1 = free
  /// type 2 = full
  Room res;
  if(type == 1)
    res = {ri - le + 1, ri - le + 1, ri - le + 1, 1, 0};
  else
    res = {0, 0, 0, 0, 1};
  return res;
}

Room merge_nodes(Room a, Room b) {
  /// 1 - free
  /// 2 - full
  Room res;

  res.best = max(a.best, b.best);
  res.best = max(res.best, a.mri + b.mle);

  if(a.type1 == 1)
    res.mle = a.mle + b.mle;
  else
    res.mle = a.mle;

  if(b.type1 == 1)
    res.mri = a.mri + b.mri;
  else
    res.mri = b.mri;

  if(a.type1 == 1 && b.type1 == 1)
    res.type1 = 1;
  else
    res.type1 = 0;

  if(a.type2 == 1 && b.type2 == 1)
    res.type2 = 1;
  else
    res.type2 = 0;
  return res;
}

void build_tree(int node, int le, int ri) {
  if(le == ri) {
    aint[node] = make_node(le, ri, 1);
    return;
  }

  int mid = (le + ri) / 2;
  build_tree(2 * node, le, mid);
  build_tree(2 * node + 1, mid + 1, ri);

  aint[node] = merge_nodes(aint[2 * node], aint[2 * node + 1]);
}

void update(int node, int le, int ri, int from, int to, int type) {
  int mid = (le + ri) / 2;

  if(aint[node].type1 == 1) {
    aint[2 * node] = make_node(le, mid, 1);
    aint[2 * node + 1] = make_node(mid + 1, ri, 1);
  }

  if(aint[node].type2 == 1){
    aint[2 * node] = make_node(le, mid, 0);
    aint[2 * node + 1] = make_node(mid + 1, ri, 0);
  }

  if(from <= le && ri <= to) {
    if(type == 0)
      aint[node] = make_node(le, ri, 1);
    else
      aint[node] = make_node(le, ri, 0);
    return;
  }

  if(from <= mid)
    update(2 * node, le, mid, from, to, type);
  if(mid < to)
    update(2 * node + 1, mid + 1, ri, from, to, type);

  aint[node] = merge_nodes(aint[2 * node], aint[2 * node + 1]);
}

int main()
{
  in >> n >> p;
  build_tree(1, 1, n);

  for(int i = 1; i <= p; i++) {
    int op, x, y;
    in >> op;
    if(op != 3)
      in >> x >> y;
    if(op == 1)
      update(1, 1, n, x, x + y - 1, 1);
    else if(op == 2)
      update(1, 1, n, x, x + y - 1, 0);
    else
      out << aint[1].best << '\n';
  }

  in.close();
  out.close();
  return 0;
}