Cod sursa(job #2546782)

Utilizator stormy_weatherelena cristina stormy_weather Data 14 februarie 2020 15:38:20
Problema Hotel Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.71 kb
#include<fstream>
#include<iostream>
#include<vector>
#include<set>
using namespace std;

void display_set(multiset<int> &free) {
  for (auto it = free.begin(); it != free.end(); ++it) {
    cout << *it << " ";
  }
  cout << "\n";
  return;
}

void add_interval(set <pair <int, int>> &busy, multiset <int> &free, int a, int b, int n) {
  if (busy.empty()) {
    //we have no busy rooms presently
    busy.insert({a, b});
    free.erase(free.begin());
    if (a > 1)
      free.insert(a - 1);
    if (b < n)
      free.insert(n - b);
    return;
  }
  auto after = busy.upper_bound({b, n + 1});
  if (after == busy.end()) {
    auto before = --after;
    int free_int = n - before->second;
    free.erase(free.find(free_int));
    if (b < n)
      free.insert(n - b);

    if (a - 1 == before->second) {
      int start = before->first;
      busy.erase(before);
      busy.insert({start, b});
    } else {
      busy.insert({a, b});
      free.insert(a - before->second - 1);
    }
  } else if (after == busy.begin()){
    int free_int = after->first - 1;
    free.erase(free.find(free_int));
    if (a > 1)
      free.insert(a - 1);

    if (b + 1 == after->first) {
      int end = after->second;
      busy.erase(after);
      busy.insert({a, end});
    } else {
      busy.insert({a, b});
      free.insert(after->first - b - 1);
    }
  } else {
    auto before = --after;
    int free_int = before->first - after->second - 1;
    free.erase(free.find(free_int));

    int start = before->first, end = after->second;
    if (a - 1 == before->second && b + 1 == after->first) {
      busy.erase(after);
      busy.erase(before);
      busy.insert({start, end});
    } else if (a - 1 == before->second) {
      busy.erase(before);
      busy.insert({start, b});

      free.insert(after->first - b - 1);
    } else if (b + 1 == after->first) {
      busy.erase(after);
      busy.insert({b, end});

      free.insert(a - before->second - 1);
    } else {
      busy.insert({a, b});

      free.insert(after->first - b - 1);
      free.insert(a - before->second - 1);
    }
  }
  return;
}

void remove_interval(set <pair <int, int>> &busy, multiset <int> &free, int a, int b, int n) {
  auto it = busy.upper_bound({b, n + 1});
  auto busy_int = --it;
  int start = busy_int->first, end = busy_int->second;

  int free_before, free_after, delete_start, delete_end;
  if (a == start && b == end) {

    //no insert to busy
    if (busy_int == busy.begin()) {
      delete_start = 1;
      if (start > 1) {
        free_before = start - 1;
        free.erase(free.find(free_before));
      }
    } else {
      auto before = --busy_int;
      delete_start = before->second + 1;
      free_before = start - before->second - 1;
      free.erase(free.find(free_before));
    }

    if (busy_int == --busy.end()) {
      delete_end = n;
      if (end < n) {
        free_after = n - end;
        free.erase(free.find(free_after));
      }
    } else {
      auto after = ++busy_int;
      free_after = after->first - end - 1;
      free.erase(free.find(free_after));
      delete_end = after->first - 1;
    }
    free.insert(delete_end - delete_start + 1);
  } else if (a == start) {
    busy.insert({b + 1, end});

    if (busy_int == busy.begin()) {
      if (start > 1) {
        free_before = start - 1;
        free.erase(free.find(free_before));
      }
      free.insert(b);
    } else {
      auto before = --busy_int;
      free_before = a - before->second - 1;
      free.erase(free.find(free_before));
      // cout << "right limit of before is " << before->second << "\n";
      free.insert(b - before->second);
    }

  } else if (b == end) {
    busy.insert({start, a - 1});

    if (busy_int == --busy.end()) {
      if (end < n) {
        free_after = n - end;
        free.erase(free.find(free_after));
        free.insert(n - a + 1);
      }
    } else {
      auto after = ++busy_int;
      free_after = after->first - end - 1;
      free.erase(free.find(free_after));
      free.insert(after->first - a);
    }
  } else {
    busy.insert({start, a - 1});
    busy.insert({b + 1, end});
    free.insert(b - a + 1);
  }

  busy.erase(busy.find({start, end}));
  return;
}

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

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

  set <pair <int, int>> busy;
  multiset <int> free;
  free.insert(n);

  for (int i = 0; i < p; i++) {
    int t; fin >> t;
    if (t == 3) {
      if (free.empty())
        fout << "0 \n";
      else {
        auto big = --free.end();
        fout << *big << "\n";
      }
    } else if (t == 1) {
      int a, b; fin >> a >> b;
      add_interval(busy, free, a, a + b - 1, n);
    } else if (t == 2) {
      int a, b; fin >> a >> b;
      remove_interval(busy, free, a, a + b -1, n);
    }
    // display_set(free);
  }

  return 0;
}