Cod sursa(job #2544900)

Utilizator stormy_weatherelena cristina stormy_weather Data 12 februarie 2020 17:33:21
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.56 kb
#include<fstream>
#include<iostream>
#include<vector>
using namespace std;

struct interval {
  int count, free, max_sec, left_sec, right_sec, debt;
  interval(int c = 0, int f = 0, int m = 0, int left = 0, int right = 0, int d = 0) {
    count = c;
    free = f;
    max_sec = m;
    left_sec = left;
    right_sec = right;
    debt = d;
  }
};

void update_room(interval &room, int left, int right, int val) {
  int all = right - left + 1;
  if (val == 1)
    room = {all, 0, 0, 0, 0, 1};
  else if (val == -1)
    room = {all, all, all, all, all, -1};
  else if (val == 0)
    room = {all, all, all, all, all, 0};
}

void propagate(vector <interval> &rooms, int node, int left, int right) {
  if (rooms[node].debt != 0) {
    int middle = (left + right) / 2;
    update_room(rooms[2 * node], left, middle, rooms[node].debt);
    update_room(rooms[2 * node + 1], middle + 1, right, rooms[node].debt);
    rooms[node].debt = 0;
  }
}

interval get_parent_interval(interval left, interval right) {
  interval parent;
  parent.count = left.count + right.count;
  parent.free = left.free + right.free;

  parent.max_sec = max(max(left.max_sec, right.max_sec), left.right_sec + right.left_sec);

  if (left.count == left.free)
    parent.left_sec = left.free + right.left_sec;
  else
    parent.left_sec = left.left_sec;

  if (right.count == right.free)
    parent.right_sec = right.free + left.right_sec;
  else
    parent.right_sec = right.right_sec;

  parent.debt = 0;
  return parent;
}

void act(vector <interval> &rooms, int node, int left, int right, int i_left, int i_right, int val) {
  if (left >= i_left && right <= i_right) {
    update_room(rooms[node], left, right, val);
    return;
  }
  propagate(rooms, node, left, right);
  int middle = (left + right) / 2;
  if (i_left <= middle) {
    act(rooms, 2 * node, left, middle, i_left, i_right, val);
  }
  if (i_right > middle) {
    act(rooms, 2 * node + 1, middle + 1, right, i_left, i_right, val);
  }
  rooms[node] = get_parent_interval(rooms[2 * node], rooms[2 * node + 1]);
}

int main() {
  ifstream fin("hotel.in");
  ofstream fout("hotel.out");

  int n, p; fin >> n >> p;

  vector <interval> rooms(4 * n);
  for (int i = 1; i <= n; i++)
    act(rooms, 1, 1, n, i, i, 0);

  for (int i = 0; i < p; i++) {
    int t; fin >> t;
    if (t == 3) {
      interval cur_int = rooms[1];
      fout << cur_int.max_sec << "\n";
    } else if (t == 1) {
      int a, b; fin >> a >> b;
      act(rooms, 1, 1, n, a, a + b - 1, 1);
    } else if (t == 2) {
      int a, b; fin >> a >> b;
      act(rooms, 1, 1, n, a, a + b - 1, -1);
    }
  }

  return 0;
}