Cod sursa(job #1692308)

Utilizator stoianmihailStoian Mihail stoianmihail Data 20 aprilie 2016 17:16:42
Problema Hotel Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.13 kb
#include <stdio.h>
#include <set>

using std::set;

#define treeSize 131072
#define Nadejde 100000

int N, M;
char sign[Nadejde + 2];
int tree[2 * treeSize];

set <int> sl;
set <int>::iterator it;

int MAX(int X, int Y) {
  return X > Y ? X : Y;
}

void init() {
  int i;

  for (i = 1; i <= N; i++) {
    sign[i] = '0';
  }
}

void update(int u, int left, int right, int pos, int val) {
  int mid = (left + right) >> 1;

  if (left == right) {
    tree[u] = val;
    return;
  }

  if (pos <= mid) {
    update(2 * u, left, mid, pos, val);
  } else {
    update(2 * u + 1, mid + 1, right, pos, val);
  }
  tree[u] = MAX(tree[2 * u], tree[2 * u + 1]);
}


void add(int x, int val) {
  if (val == 1) {
    update(1, 1, N, x, x);
  } else {
    update(1, 1, N, x, val);
  }
}

void push(int x, char c) {
  sl.insert(x);
  sign[x] = c;
}

void pop(int x) {
  sl.erase(x);
  sign[x] = '0';
}

int left(int x) {
  it = sl.lower_bound(x);
  if (it == sl.begin()) {
    return 1;
  } else {
    it--;
    return *it;
  }
}

int right(int x) {
  it = sl.upper_bound(x);
  if (it == sl.end()) {
    return N + 1;
  } else {
    return *it;
  }
}

int main(void) {
  int i, a, b, task, lo, hi;
  FILE *f = fopen("hotel.in", "r");
  freopen("hotel.out", "w", stdout);

  fscanf(f, "%d %d", &N, &M);
  init();

  /* Raspunde la intrebari. */
  for (i = 1; i <= M; i++) {
    fscanf(f, "%d", &task);
    if (task == 1) {
      fscanf(f, "%d %d", &a, &b);
      b += a - 1;

      /* Trebuie sa fim fix sub "a". */
      if (!sl.empty()) {
        it = sl.upper_bound(a);
        it--;
        if (it == sl.begin()) {
          lo = 1;
        } else {
          lo = *it;
        }
        it++;
        if (it == sl.end()) {
          hi = N + 1;
        } else {
          hi = *it;
        }
      } else {
        lo = 1;
        hi = N + 1;
      }
      add(hi - lo, -1);
      add(a - lo, +1);
      add(hi - b - 1, +1);

      if (sign[a] == '-') {
        pop(a);
      } else {
        push(a, '+');
      }
      if (sign[b + 1] == '+') {
        pop(b + 1);
      } else {
        push(b + 1, '-');
      }
    } else if (task == 2) {
      fscanf(f, "%d %d", &a, &b);
      b += a - 1;

      /* Stergem o secventa inclusa intr-un sir de "1". */
      if (sign[a] != '+' && sign[b + 1] != '-') {
        sign[a] = '-';
        sign[b + 1] = '+';
        add(b - a + 1, +1);
      /* Stergem prefixul unui sir de "1". */
      } else if (sign[a] == '+' && sign[b + 1] != '-') {
        pop(a);
        push(b + 1, '+');

        lo = left(a);
        add(a - lo, -1);
        add(b - lo + 1, +1);
      /* Stergem sufixul unui sir de "1". */
      } else if (sign[a] != '+' && sign[b + 1] == '-') {
        push(a, '-');
        pop(b + 1);

        hi = right(b + 1);
        add(hi - b - 1, -1);
        add(hi - a, +1);
      /* Stergem un sir de "1". */
      } else {
        pop(a);
        pop(b + 1);

        lo = left(a);
        hi = right(b + 1);
        add(hi - b - 1, -1);
        add(a - lo, -1);
        add(hi - lo, +1);
      }
    } else {
      fprintf(stdout, "%d\n", tree[1]);
    }
  }
  fclose(f);
  fclose(stdout);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}