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 <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <queue>
#include <stack>
#include <tuple>
#include <cmath>
#include <iomanip>
#include <map>
#include <cstring> //memset(dp,0,sizeof(dp))
#include <functional>
#define ll long long
#define rep(i,n) for(int i=0;i<(n);i++)
#define rrep(i,n) for(int i=n-1;i>=0;i--)
#define fi first
#define se second
#define pb push_back
#define ALL(a) (a).begin(),(a).end()
using namespace std;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
typedef pair<ll,ll> P;
typedef pair<ll,ll> Pll;
//小数点以下　cout << fixed << setprecision(10) << num << endl;
//桁数はlog10(mid)でやれ　log(mid)/log(10)はWA
//long*long<0で判定するな
//開区間と閉区間
//アルファベットが何番目かは x=s[i]-'a'
//bfsはmain()内で　rep(i,h)rep(j,w)rep(i,4)でバグ
//切り上げ：(a+(b-1))/b
//32bit以上は 1ull<<j
// map 初期値0 for(auto itr=mp.begin();itr!=mp.end();++itr) itr->fi itr->se で全探索
// for(auto u:mp) u.fi u.se も可能
//n個のgcd,lcmは一つずつみて更新していく
//大きな数を扱うときは素因数分解した形で持っておく
// (l/a[i]) = l*powmod(a[i],MOD-2)%MOD;
//auto itr=lower_bound(ALL(a),key) a[itr-a.begin()]

template<typename T>
struct SegmentTree{
    int n;
    T e; //単位元
    vector<T> v;
    function<T(T,T)> operation;
    function<T(T,T)> update;
    //区間[a,b)に対してのクエリ 今は[l,r)を見ている
    T _query(int a,int b,int k,int l,int r){
        if(r<=a||b<=l) return e;
        if(a<=l && r<=b) return v[k];
        else{
            T c1=_query(a,b,2*k+1,l,(l+r)/2);
            T c2=_query(a,b,2*k+2,(l+r)/2,r);
            return operation(c1,c2);
        }
    }
public:
    SegmentTree(size_t _n,T _e,function<T(T,T)> _operation,function<T(T,T)> _update):e(_e),operation(_operation),update(_update){
        n=1;
        while(n<_n){
            n*=2;
        }
        v=vector<T>(2*n-1,e);
    }
    void change(int i,T x){
        i+=n-1;
        v[i]=update(v[i],x);
        while(i>0){
            i=(i-1)/2;
            v[i]=operation(v[i*2+1],v[i*2+2]);
        }
    }
    T query(int a,int b){
        return _query(a,b,0,0,n);
    }
    T operator[](int i){
        return v[i+n-1];
    }
};
//veryfi
int main(){
    int n,q; cin >> n >> q;
    SegmentTree<ll> st(n,(1ull<<31)-1,[](ll a,ll b){return min(a,b);},[](ll a,ll b){return b;});
    rep(i,q){
        bool x; cin >> x;
        int a1,a2; cin >> a1 >> a2;
        if(x){
            cout << st.query(a1,a2+1)<<endl;
        }else{
            st.change(a1,a2);
        }
    }
    //加算ならうupdateに渡すラムダ式は[](int a,b){return a+b;}とする（？）
}