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;

template <typename monoid>
class segmentTree {
public:
  using M = monoid;
  using T = typename M::value_type;

  int sz;
  vector<T> x;

  segmentTree(int n = 1e5) {
    sz = 1; while(sz < n) sz *= 2;
    init();
  }
  void init() { x.assign(sz*2, M::id()); }

  // [a, b)
  T query(int a, int b, int k, int l, int r) {
    if(r <= a || b <= l) return M::id();
    if(a <= l && r <= b) return x[k];
    return M::f(query(a, b, 2*k+1, l, (l+r)/2),
                query(a, b, 2*k+2, (l+r)/2, r));
  }
  T query(int a, int b) {return query(a, b, 0, 0, sz);}
  // 点更新
  void update(int i, const T &val) {
    i += sz-1;
    x[i] = M::g(x[i], val);
    while(i > 0) {
      i = (i-1) / 2;
      x[i] = M::f(x[i*2+1], x[i*2+2]);
    }
  }
};

template <typename T>
struct min_monoid {
  using value_type = T;
  static constexpr T id() { return std::numeric_limits<T>::max(); }
  static T f(const T &a, const T &b) { return min(a, b); }
  static T g(const T &a, const T &b) { return b; }
};
template <typename T>
struct max_monoid {
  using value_type = T;
  static constexpr T id() { return std::numeric_limits<T>::min; }
  static T f(const T &a, const T &b) { return max(a, b); }
  static T g(const T &a, const T &b) { return b; }
};
template <typename T>
struct sum_monoid {
  using value_type = T;
  static constexpr T id() {return 0;}
  static T f(const T &a, const T &b) { return a+b; }
  static T g(const T &a, const T &b) { return a+b; }
};

template <typename T>
using rmq = segmentTree<min_monoid<T>>;
template <typename T>
using rsq = segmentTree<sum_monoid<T>>;

signed main() {
  int n, q;
  cin >> n >> q;
  rmq<int> seg(n);
  for(int i=0; i<q; ++i) {
    int c, x, y;
    cin >> c >> x >> y;
    if(c == 0) {
      seg.update(x, y);
    } else {
      cout << seg.query(x, y+1) << endl;
    }
  }

  return 0;
}