Cod sursa(job #2139823)

Utilizator eftimie1Alex Efrim eftimie1 Data 22 februarie 2018 20:16:34
Problema Hotel Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
#include <iostream>
#include <fstream>

using namespace std;

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

int const nmax = 100000;

struct Node {
  int sol;
  int le;
  int ri;
  bool empty;
  bool full;

  void initempty(int from, int to) {
    sol = to - from + 1;
    le = to - from + 1;
    ri = to - from + 1;
    empty = true;
    full = false;
  }

  void initfull() {
    sol = 0;
    le = 0;
    ri = 0;
    empty = false;
    full = true;
  }
};

int n, p;
Node aint[1 + 4 * nmax];

void compute(int node) {
  aint[node].sol = max(aint[2 * node].sol, aint[2 * node + 1].sol);
  aint[node].sol = max(aint[node].sol, aint[2 * node].ri + aint[2 * node + 1].le);

  if (aint[2 * node].empty)
    aint[node].le = aint[2 * node].le + aint[2 * node + 1].le;
  else
    aint[node].le = aint[2 * node].le;

  if (aint[2 * node + 1].empty)
    aint[node].ri = aint[2 * node].ri + aint[2 * node + 1].ri;
  else
    aint[node].ri = aint[2 * node + 1].ri;

  if (aint[2 * node].empty && aint[2 * node + 1].empty)
    aint[node].empty = true;
  else
    aint[node].empty = false;

  if (aint[2 * node].full && aint[2 * node + 1].full)
    aint[node].full = true;
  else
    aint[node].full = false;
}

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

void inherit(int node, int from, int to) {
  int mid = (from + to) / 2;
  if(aint[node].full) {
    aint[2 * node].initfull();
    aint[2 * node + 1].initfull();
  } else if(aint[node].empty) {
    aint[2 * node].initempty(from, mid);
    aint[2 * node + 1].initempty(mid + 1, to);
  }
}

void update(int node, int from, int to, int x, int y, bool fill) {
  if(from == x && to == y) {
    if(fill == true)
      aint[node].initfull();
    else
      aint[node].initempty(from, to);
    inherit(node, from, to);
  } else {
    inherit(node, from, to);
    int mid = (from + to) / 2;
    if(x <= mid)
      update(2 * node, from, mid, x, min(y, mid), fill);
    if(mid + 1 <= y)
      update(2 * node + 1, mid + 1, to, max(x, mid + 1), y, fill);
    compute(node);
  }
}

int main() {
  in >> n >> p;
  buildtree(1, 1, n);
  for (int i = 1; i <= p; i++) {
    int query;
    in >> query;
    if (query == 1 || query == 2) {
      int from, to;
      in >> from >> to;
      to = from + to - 1;

      int fill = 2 - query; //1 means fill, 2 means empty
      update(1, 1, n, from, to, fill);
    } else
      out << aint[1].sol << '\n';
  }
  return 0;
}