Cod sursa(job #2014655)

Utilizator dementorrDementhor dementorr Data 24 august 2017 11:38:56
Problema Hotel Scor 10
Compilator c Status done
Runda Arhiva de probleme Marime 3.68 kb
#include <stdio.h>

typedef struct
{
  int left, right, max;
  int update;
} Node;
Node A[400000];

int maximum (int a, int b) {
  if (a > b)
    return a;
  else
    return b;
}

int minimum (int a, int b) {
  if (a < b)
    return a;
  else
    return b;
}

// ....[a.....(l......r)....b]....
int inclus (int l, int r, int a, int b) {
  return a <= l && r <= b;
}

// ....(l.....[a......r)....b]....
int intersect (int l, int r, int a, int b) {
  return l <= b && a <= r;
}

// update (1, 1, n, 2, 4, 5)
void update (int nod, int left, int right, int a, int b, int value) {
  //printf ("Update nod = %d\t left = %d\t right = %d\t a = %d\t b = %d, value = %d, update = %d\n", nod, left, right, a, b, value, A[nod].update);
  
  if (left == right) {  
    A[nod].left = minimum(1, value);
    A[nod].right = minimum(1, value);
    A[nod].max = minimum(1, value);
    A[nod].update = 0;
    
    return;
  }

  // update with flags when ppl leave or come
  if (inclus (left, right, a, b)) {
    A[nod].left = value;
    A[nod].right = value;
    A[nod].max = value;
    A[nod].update = 1;
    
    return;
  }

  int middle = (left + right) >> 1;
  // Trebuie sa impingem valorile
  if (A[nod].update == 1) {
    A[nod].update = 0;

    if (A[nod].max == 0) {
      A[nod * 2].left = 0;
      A[nod * 2].right = 0;
      A[nod * 2].max = 0;
      A[nod * 2].update = 1;

      A[nod * 2 + 1].left = 0;
      A[nod * 2 + 1].right = 0;
      A[nod * 2 + 1].max = 0;
      A[nod * 2 + 1].update = 1;
    } else {
      A[nod * 2].left = middle - left + 1;
      A[nod * 2].right = middle - left + 1;
      A[nod * 2].max = middle - left + 1;
      A[nod * 2].update = 1;

      A[nod * 2 + 1].left = right - middle;
      A[nod * 2 + 1].right = right - middle;
      A[nod * 2 + 1].max = right - middle;
      A[nod * 2 + 1].update = 1;
    }
  }
  
  if (intersect (left, middle, a, b))
    update (nod * 2, left, middle, a, b, value);
  if (intersect (middle + 1, right, a, b))
    update (nod * 2 + 1, middle + 1, right, a, b, value);

  // Update left
  if (A[nod * 2].max == middle - left + 1) { // Daca left e full
    A[nod].left = A[nod * 2].left + A[nod * 2 + 1].left;
  } else { // Ramane cel de left
    A[nod].left = A[nod * 2].left;
  }

  // Update right
  if (A[nod * 2 + 1].max == right - middle) { // Daca right e full
    A[nod].right = A[nod * 2 + 1].right + A[nod * 2].right;
  } else { // Ramane cel de right
    A[nod].right = A[nod * 2 + 1].right;
  }

  // Update max: este max_left sau max_right sau final_left + inceput_right
  A[nod].max = maximum(maximum(A[nod * 2].max, A[nod * 2 + 1].max), A[nod * 2].right + A[nod * 2 + 1].left);
  A[nod].update = 0;
}

int main() {
  freopen ("hotel.in",  "r", stdin);
  freopen ("hotel.out", "w", stdout);
  
  int n, m;
  scanf ("%d %d", &n, &m);

  int j;
  for (j = 1; j <= n; ++j) {
    update (1, 1, n, j, j, 1);
  }

  /*
  for (j = 1; j <= 32; ++j)
    printf ("Nod = %d,\t stg = %d,\t max = %d,\t dr = %d,\t update = %d\n",
	    j, A[j].left, A[j].max, A[j].right, A[j].update);
    
  return 0;
  */

  //update (1, 1, n, 1, n, n);
  int i;
  for (i = 0; i < m; ++i) {
    int op;
    scanf ("%d", &op);

    if (op == 1) {
      int left, right, add;
      scanf ("%d %d", &left, &add);
      right = left + add - 1;

      update (1, 1, n, left, right, 0);
    } else if (op == 2) {
      int left, right, add;
      scanf ("%d %d", &left, &add);
      right = left + add - 1;

      update (1, 1, n, left, right, add);
    } else if (op == 3) {
      printf ("%d\n", A[1].max);
    }

    /*
    int j;
    for (j = 1; j <= 32; ++j)
    printf ("Nod = %d,\t stg = %d,\t max = %d,\t dr = %d,\t update = %d\n",
	    j, A[j].left, A[j].max, A[j].right, A[j].update);
    */
  }
  
  return 0;
}