Cod sursa(job #2143070)

Utilizator GoogalAbabei Daniel Googal Data 25 februarie 2018 15:53:53
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <iostream>
#include <fstream>

using namespace std;

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

const int NMAX = 1e5;

struct Node {
  //campurin arbore intervale
  int best;
  int maxleft;
  int maxright;

  //campuri de update lazy
  bool full;
  bool empty;

  void initfull(int node, int from, int to) {
    best = 0;
    maxleft = 0;
    maxright = 0;
    full = 1;
    empty = 0;
  }

  void initempty(int node, int from, int to) {
    best = to - from + 1;
    maxleft = best;
    maxright = best;
    full = 0;
    empty = 1;
  }
};

Node arb[1 + 4 * NMAX];

//node nu e frunza
//node e curat
//node are fiii curati
void computenode(int node, int from, int to) {
  Node &a = arb[2 * node];
  Node &b = arb[2 * node + 1];

  arb[node].best = max(a.maxright + b.maxleft, max(a.best,  b.best));
  if(a.empty == true)
    arb[node].maxleft = a.maxleft + b.maxleft;
  else
    arb[node].maxleft = a.maxleft;

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

  if(a.empty && b.empty)
    arb[node].empty = 1;
  else
    arb[node].empty = 0;

  if(a.full && b.full)
    arb[node].full = 1;
  else
    arb[node].full = 0;
}

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

    buildtree(2 * node, from, mid);
    buildtree(2 * node + 1, mid + 1, to);

    computenode(node, from, to);
  }
}

//aici ai flexibilitate
void cleannode(int node, int from, int to) {
  if(from < to) {
    int mid = (from + to) / 2;
    if(arb[node].empty == 1) {
      arb[2 * node].initempty(2 * node, from, mid);
      arb[2 * node + 1].initempty(2 * node + 1, mid + 1, to);
    } else if(arb[node].full == 1) {
      arb[2 * node].initfull(2 * node, from, mid);
      arb[2 * node + 1].initfull(2 * node + 1, mid + 1, to);
    }
  }
}

void update(int node, int from, int to, int x, int y, int v) {
  if(from == x && to == y) {
    if(v == 1)
      arb[node].initfull(node, from, to);
    else
      arb[node].initempty(node, from, to);
  } else {
    cleannode(node, from, to);
    int mid = (from + to) / 2;
    if(x <= mid)
      update(2 * node, from, mid, x, min(y, mid), v);  //nu va fi mereu x si y
    if(mid + 1 <= y)
      update(2 * node + 1, mid + 1, to, max(x, mid + 1), y, v);
    computenode(node, from, to);
  }
}

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

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

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