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)

using System;
using System.Linq;

class Program
{
    static int n;
    static int q;
    static RMQ rmq;

    static void Main()
    {
        int[] input = Console.ReadLine().Split().Select(int.Parse).ToArray();
        n = input[0];
        q = input[1];
        rmq = new RMQ(n, (int)(Math.Pow(2, 31) - 1));

        for (int i = 0; i < q; i++)
        {
            input = Console.ReadLine().Split().Select(int.Parse).ToArray();
            if (input[0] == 0) // update
            {
                int x = input[1];
                int y = input[2];
                rmq.Update(x, y);
                continue;
            }
            // find
            Console.WriteLine(rmq.Query(input[1], input[2] + 1));
        }
    }
}

struct RMQ
{
    private int n;
    private int[] dat;
    public int Length { get; private set; }

    /* nを要素数として、すべてint.MaxValueで初期化 */
    public RMQ(int n)
    {
        Length = n;
        this.n = 1;
        while (this.n < n) this.n *= 2;
        dat = new int[2 * this.n];
        for (int i = 0; i < 2 * this.n - 1; i++)
            dat[i] = int.MaxValue;
    }

    /* nを要素数として、すべてNで初期化 */
    public RMQ(int n, int N)
    {
        Length = n;
        this.n = 1;
        while (this.n < n) this.n *= 2;
        dat = new int[2 * this.n];
        for (int i = 0; i < 2 * this.n - 1; i++)
            dat[i] = N;
    }

    /* k番目(0-indexed)をaに変更 */
    public void Update(int k, int a)
    {
        k += n - 1;
        dat[k] = a;
        while (k > 0)
        {
            k = (k - 1) / 2;
            dat[k] = Math.Min(dat[k * 2 + 1], dat[k * 2 + 2]);
        }
    }

    private int Query_(int a, int b, int k, int l, int r)
    {
        if (r <= a || b <= l) return int.MaxValue;
        if (a <= l && r <= b) return dat[k];
        int v1 = Query_(a, b, k * 2 + 1, l, (l + r) / 2);
        int v2 = Query_(a, b, k * 2 + 2, (l + r) / 2, r);
        return Math.Min(v1, v2);
    }

    /* [a,b)の最小値を求める */
    public int Query(int a, int b)
    {
        return Query_(a, b, 0, 0, n);
    }
}