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: Accepted)

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

int min(int a, int b) {
    return (a < b) ? a : b;
}

typedef struct node {
    int value, size;
    struct node *lch, *rch;
} node_t;

typedef node_t* segtree_t;

void combine_segtree(segtree_t root) {
    root->size = root->lch->size + root->rch->size;
    root->value = min(root->lch->value, root->rch->value);
}

segtree_t make_segtree(int size) {
    segtree_t root = (segtree_t)malloc(sizeof(node_t));
    root->size = size;
    root->value = INT_MAX;
    root->lch = root->rch = NULL;
    if (size == 1) return root;
    root->lch = make_segtree(size / 2);
    root->rch = make_segtree(size - size / 2);
    combine_segtree(root);
    return root;
}

void free_segtree(segtree_t root) {
    if (root->lch) free(root->lch);
    if (root->rch) free(root->rch);
    free(root);
}

void update_segtree(segtree_t root, int k, int x) {
    if (root->lch == NULL && root->rch == NULL) {
        free_segtree(root);
        root = make_segtree(1);
        if (k == 0) root->value = x;
    }
    else if (k < root->lch->size) {
        update_segtree(root->lch, k, x);
        combine_segtree(root);
    }
    else {
        int lsize = root->lch->size;
        update_segtree(root->rch, k - lsize, x);
        combine_segtree(root);
    }
}

int min_query(segtree_t root, int a, int b) {
    if (root->lch == NULL)
        return (a <= 0 && b > 0)
            ? root->value
            : INT_MAX;
    if (a <= 0 && root->size <= b) return root->value;
    if (b <= 0 || root->size <= a) return INT_MAX;
    int lsize = root->lch->size,
        left = min_query(root->lch, a, b),
        right = min_query(root->rch, a - lsize, b - lsize);
    return min(left, right);
}

enum command { Update, Find, };

int main(void) {
    int n, q, i;
    scanf("%d%d", &n, &q);
    segtree_t rmq = make_segtree(n);
    for (i = 0; i < q; i++) {
        int com, x, y;
        scanf("%d%d%d", &com, &x, &y);
        switch (com) {
            case Update:
                update_segtree(rmq, x, y);
                break;
            case Find:
                printf("%d\n", min_query(rmq, x, y + 1));
        }
    }
    free_segtree(rmq);
    return 0;
}