Cod sursa(job #1996128)

Utilizator dementorrDementhor dementorr Data 30 iunie 2017 11:37:51
Problema Hotel Scor 10
Compilator c Status done
Runda Arhiva de probleme Marime 3.41 kb
#include <stdio.h>

typedef struct
{
  int left, right, max;
} 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\n", nod, left, right, a, b, value);
  
  value = minimum (value, right - left + 1);
  if (left == right) {
    
    A[nod].left = value;
    A[nod].right = value;
    A[nod].max = value;
    
    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;

    return;
  }

  int middle = (left + right) >> 1;
  // Toate sunt egale si toate deci trebuie sa impingem cele doua valori
  if (A[nod].left == A[nod].right && A[nod].right == A[nod].max) {

    int new_value_left  = middle - left + 1;
    int new_value_right = right - middle;
    if (A[nod].left == 0) {
      new_value_left = 0;
      new_value_right = 0;
    }
     
    // Update left node
    A[nod * 2].left  = new_value_left;
    A[nod * 2].right = new_value_left;
    A[nod * 2].max   = new_value_left;

    // Update right node
    A[nod * 2 + 1].left  = new_value_right;
    A[nod * 2 + 1].right = new_value_right;
    A[nod * 2 + 1].max   = new_value_right;
  }
  
  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);

  A[nod].max = maximum(A[nod * 2].max, A[nod * 2 + 1].max);
  A[nod].max = maximum(A[nod].max, A[nod * 2].right + A[nod * 2 + 1].left);

  A[nod].left = A[nod * 2].left;
  if (A[nod * 2].left == A[nod * 2].max && A[nod * 2].max == middle - left + 1) { // E complet
    A[nod].left += A[nod * 2 + 1].left;
  }    
  
  A[nod].right = A[nod * 2 + 1].right;

  if (A[nod * 2 + 1].right == A[nod * 2 + 1].max && A[nod * 2 + 1].max == right - middle) { // E complet
    A[nod].right += A[nod * 2].right;
  }
}

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);
  }

  update (1, 1, n, 1, n, 0);
  update (1, 1, n, 1, 6, 6);
  update (1, 1, n, 7, 9, 3);
  for (j = 1; j <= 32; ++j)
    printf ("Nod = %d,\t max = %d,\t stg = %d,\t dr = %d\n",
	    j, A[j].max, A[j].left, A[j].right);
    
  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);
    }

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