Cod sursa(job #2095104)

Utilizator stefan_creastaStefan Creasta stefan_creasta Data 26 decembrie 2017 22:20:31
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 kb
#include <cstdio>
#include <algorithm>
using namespace std;
const int NMAX = 300005;
struct Interval {
  int st;
  int dr;
  int maxim;
  bool free;
  bool full;
};
Interval aint[4 * NMAX];
Interval join(const Interval &a, const Interval &b) {
  Interval nod;
  nod.maxim = max(max(a.maxim, b.maxim), a.dr + b.st);
  if(b.free == true)
    nod.dr = b.dr + a.dr;
  else
    nod.dr = b.dr;
  if(a.free == true)
    nod.st = a.st + b.st;
  else
    nod.st = a.st;
  if(a.free == true && b.free == true)
    nod.free = true;
  else
    nod.free = false;
  if(a.full == true && b.full == true)
    nod.full = true;
  else
    nod.full = false;
  return nod;
}
Interval create_free(int st, int dr) {
  Interval nod;
  int lung = dr - st + 1;
  nod.st = lung;
  nod.dr = lung;
  nod.maxim = lung;
  nod.free = true;
  nod.full = false;
  return nod;
}
Interval create_full(int st, int dr) {
  Interval nod;
  nod.st = 0;
  nod.dr = 0;
  nod.maxim = 0;
  nod.free = false;
  nod.full = true;
  return nod;
}
void update(int nod, int a, int b, int st, int dr, bool val) {
  if(aint[nod].free == true) {
    int mij = (st + dr) / 2;
    aint[2 * nod] = create_free(st, mij);
    aint[2 * nod + 1] = create_free(mij + 1, dr);
  }
  if(aint[nod].full == true){
    int mij = (st + dr) / 2;
    aint[2 * nod] = create_full(st, mij);
    aint[2 * nod + 1] = create_full(mij + 1, dr);
  }
  if(a <= st && dr <= b) {
    if(val == 0) {
      aint[nod] = create_free(st, dr);
    }
    else {
      aint[nod] = create_full(st, dr);
    }
  }
  else {
    int mij = (st + dr) / 2;
    if(a <= mij) {
      update(2 * nod, a, b, st, mij, val);
    }
    if(mij + 1 <= b){
      update(2 * nod + 1, a, b, mij + 1, dr, val);
    }
    aint[nod] = join(aint[2 * nod], aint[2 * nod + 1]);
  }
}
void update(int a, int b, bool val, int n) {
  update(1, a, b, 1, n, val);
}
void first_update(int nod, int st, int dr) {
  if(st == dr) {
    aint[nod] = create_free(st, dr);
  }
  else {
    int mij = (st + dr) / 2;
    first_update(2 * nod, st, mij);
    first_update(2 * nod + 1, mij + 1, dr);
    aint[nod] = join(aint[2 * nod], aint[2 * nod + 1]);
  }
}


int main() {
  int n, m;
  freopen("hotel.in", "r", stdin);
  freopen("hotel.out", "w", stdout);
  scanf("%d%d", &n, &m);
  first_update(1, 1, n);
  for(int i = 1; i <= m; ++i) {
    int op;
    scanf("%d", &op);
    if(op == 1) {
      int x, y;
      scanf("%d%d", &x, &y);
      update(x, x + y - 1, true, n);
    }
    else if(op == 2) {
      int x, y;
      scanf("%d%d", &x, &y);
      update(x, x + y - 1, false, n);
    }
    else if(op == 3) {
      printf("%d\n", aint[1].maxim);
    }
  }
  return 0;
}