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>
#define range(i,a,b) for(int i = (a); i < (b); i++)
#define rep(i,b) for(int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x)  cerr << #x << " = " << (x) << endl;
//const int INF = 1e8;
using namespace std;

/*
struct Monoid{
    using T = _underlying_set_; //??¢??????????????°????????????
    T operator()(const T &a, const T &b) { return _a_op_b_; } //????????????
    static constexpr T identity() { return _identity_element_; } //?????????
};
*/

struct Monoid{
    using T = int; //??¢??????????????°????????????
    T operator()(const T &a, const T &b) { return a < b ? a : b; } //????????????
    static constexpr T identity() { return INT_MAX; } //?????????
};

template<class Monoid>
class SegTree{ //SegTree<Monoid> seg(n);
    private:
        using T = typename Monoid::T; //??°?????????????????¨????????¢???
        Monoid op; //???????????¢??°???????????§??????
        const int n; //????????????
        vector<T> t; //?????¨????????¨

        void prop_to(int i) { //?????????i????????¬
            t[i] = op(t[2 * i], t[2 * i + 1]);
        }

    public:
        SegTree(int n) : n(n), t(2 * n, op.identity()) {} //???????????§??????????????????
        SegTree(const vector<T> &v) : n(v.size()), t(2 * n){ //???????????¨???????????????
            copy(begin(v), end(v), begin(t) + n);
            for(int i = n - 1; i > -0; i--) prop_to(i);
        }

        void set(int i, const T &x){
            t[i += n] = x; 
            while(i >>= 1) prop_to(i);
        }

        void add(int i, const T &x){
            set(i, get(i) * x);
        }

        T get(int i) { return t[i + n]; } //??????i???????????????

        T query(int l, int r){
            T accl = op.identity(), accr = op.identity();
            for(l += n, r += n; l < r; l >>= 1, r >>= 1){
                if(l & 1) accl = op(accl, t[l++]);
                if(r & 1) accr = op(t[r-1], accr);
            }
            return op(accl, accr);
        }
};

int main(){
      int n, q;
    cin >> n >> q;

    SegTree<Monoid> seg(n);
    rep(i,q){
        int com;
        cin >> com;
        if(com){
            int x, y;
            cin >> x >> y;
            cout << seg.query(x, y + 1) << endl;
        }else{
            int x, y;
            cin >> x >> y;
            seg.set(x, y);
        }
    }
}