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++14 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
using vint = vector<int>;
using vvint = vector<vint>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vchar = vector<char>;
using vvchar = vector<vchar>;
using vp = vector<P>;
using vpp = vector<pair<P, P>>;
using vvp = vector<vp>;

#define rep(i, n) for (int i = 0; i < n; ++i)
#pragma region Debug
istream &operator>>(istream &is, P &a)
{
    return is >> a.first >> a.second;
}
ostream &operator<<(ostream &os, const P &a) { return os << "(" << a.first << "," << a.second << ")"; }

template <typename T>

void view(const std::vector<T> &v)
{
#ifndef ONLINE_JUDGE
    for (const auto &e : v)
    {
        std::cout << e << " ";
    }
    std::cout << std::endl;
#endif
}
template <typename T>
void view(const std::vector<std::vector<T>> &vv)
{
    for (const auto &v : vv)
    {
        view(v);
    }
}
#pragma endregion

const int INF = (1LL << 31) - 1;

struct segtree
{
    int n;
    vint dat;
    segtree(int count, int start)
    {
        int c = 1 << (int)(log2(count) + 1);
        dat = vint(2 * c, start);
        n = c;
    }

    void update(int i, int x)
    {
        int k = i + n;
        dat[k] = x;
        while (k / 2)
        {
            k /= 2;
            dat[k] = min(dat[k * 2], dat[k * 2 + 1]);
        }
    }

    int subGetMin(int a, int b, int k, int l, int r)
    {
        // out
        if (b <= l || a >= r)
        {
            return INF;
        }
        // completely contained
        if (a <= l && b >= r)
        {
            return dat[k];
        }
        // partially contained
        // call child
        int newK = k * 2;
        int vl = subGetMin(a, b, newK, l, (l + r) / 2);
        int vr = subGetMin(a, b, newK + 1, (l + r) / 2, r);
        return min(vl, vr);
    }

    int getMin(int a, int b)
    {
        return subGetMin(a, b, 1, 0, n);
    }
};

int main()
{
    int n, q;
    cin >> n >> q;
    segtree st(n, INF);
    rep(i, q)
    {
        int t, x, y;
        cin >> t >> x >> y;
        if (t)
        {
            int m = st.getMin(x, y + 1);
            cout << m << endl;
        }
        else
        {
            st.update(x, y);
        }
    }
    return 0;
}