Problem:
Range Minimum Query (RMQ)

Write a program which manipulates a sequence A = {a0, a1, . . . , an-1} with the following operations:

find(s, t): report the minimum element in as, as+1, . . . ,at.

update(i, x): change ai to x.

Note that the initial values of ai (i = 0, 1, . . . , n−1) are 231-1.

Input

n q
com0 x0 y0
com1 x1 y1
...
comq−1 xq−1 yq−1

In the first line, n (the number of elements in A) and q (the number of queries) are given. Then, q queries are given where com represents the type of queries. '0' denotes update(xi, yi) and '1' denotes find(xi, yi).

Output

For each find operation, print the minimum element.

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

If comi is 0, then 0 ≤ xi < n, 0 ≤ yi < 231-1.

If comi is 1, then 0 ≤ xi < n, 0 ≤ yi < n.

Sample Input 1

3 5
0 0 1
0 1 2
0 2 3
1 0 2
1 1 2

Sample Output 1

1
2

Sample Input 2

1 3
1 0 0
0 0 5
1 0 0

Sample Output 2

2147483647
5

Solution in C (judge verdict: Time Limit Exceeded)

#include <stdio.h>
#include <limits.h>

int n;
int mins[262143];

void update(int arrIndex, int val) {
  //printf("updating node %d\n", arrIndex);
  mins[arrIndex] = val;

  if (arrIndex <= 1)
    return;

  if (mins[arrIndex / 2] > val)
    update(arrIndex / 2, val);
}

int min(int n1, int n2) {
  return n1 < n2 ? n1 : n2;
}

void check(int size) {
  int i, left, right;

  for (i = 1; i < size; i++) {
    left = mins[2 * i];
    right = mins[2 * i + 1];
    if (mins[i] < left && mins[i] < right) {
      mins[i] = min(left, right);
      check(size);
      break;
    }
  }
}

int find(int node, int l, int r, int i, int j) {
  if (r < i || l > j)
    return INT_MAX;
  else if (l >= i && r <= j)
    return mins[node];
  else {
    int lValue = find(2*node, l, (l + r) / 2, i, j);
    int rValue = find((2*node)+1, (l + r) / 2 + 1, r, i, j);

    return lValue < rValue ? lValue : rValue;
  }
}

int main() {
  int q, i, j, query, counter, cur, powerOf2[18], lengthOfBottomRow;

  scanf("%d %d", &n, &q);

  for (i = 0; i < 19; i++) {
    cur = 2;

    for (j = 0; j < i; j++)
      cur *= 2;

    powerOf2[i] = cur;

    if (i) {
      if (powerOf2[i-1] <= 2 * n && powerOf2[i] >= 2 * n) {
        lengthOfBottomRow = powerOf2[i-1];
        break;
      }
    }
  }

  for (counter = 1; counter < lengthOfBottomRow * 2; counter++)
    mins[counter] = INT_MAX;

  for (counter = 0; counter < q; counter++) {
    scanf("%d %d %d", &query, &i, &j);

    if (query)
      printf("%d\n", find(1, lengthOfBottomRow, (lengthOfBottomRow * 2) - 1, i + lengthOfBottomRow, j + lengthOfBottomRow));
    else {
      update(i + lengthOfBottomRow, j);
      check(lengthOfBottomRow);
    }
  }
}