Problem p02345 (C++)

Buggy submission (status: Runtime Error):
// ???????????????
#include <cassert>
#include <climits>
#include <vector>
// ?????°
const int INF = INT_MAX;
// ?????????
class RangeMinimumQuery {
public:
  explicit RangeMinimumQuery(int s);
  void update(int i, int v);
  int index(int left, int right) const;
  int value(int left, int right) const;

private:
  int parent(int node) const;
  int left_child(int node) const;
  int right_child(int node) const;
  int power_of_two(int n) const;
  int query(int left, int right, int node, int node_left, int node_right) const;
  int size_, nil_, inf_;
  std::vector<int> index_, value_;
};
// ????????????
RangeMinimumQuery::RangeMinimumQuery(int s)
    : size_(power_of_two(s)), nil_(size_), inf_(INF),
      index_(2 * size_ - 1, nil_), value_(size_ + 1, inf_) {}
void RangeMinimumQuery::update(int i, int v) {
  int node = i + size_ - 1;
  index_.at(node) = i;
  value_.at(i) = v;
  while ((node = parent(node)) != nil_) {
    int l = value_.at(index_.at(left_child(node)));
    int r = value_.at(index_.at(right_child(node)));
    index_.at(node) = index_.at(l <= r ? left_child(node) : right_child(node));
  }
}
int RangeMinimumQuery::index(int left, int right) const {
  return query(left, right, 0, 0, size_ - 1);
}
int RangeMinimumQuery::value(int left, int right) const {
  return value_.at(query(left, right, 0, 0, size_ - 1));
}
int RangeMinimumQuery::parent(int node) const {
  return node ? (node - 1) / 2 : nil_;
}
int RangeMinimumQuery::left_child(int node) const { return 2 * node + 1; }
int RangeMinimumQuery::right_child(int node) const { return 2 * node + 2; }
int RangeMinimumQuery::power_of_two(int n) const {
  while (n & (n - 1))
    n += n & -n;
  return n;
}
int RangeMinimumQuery::query(int left, int right, int node, int node_left,
                             int node_right) const {
  assert(left <= right);
  assert(0 <= left);
  assert(size_ < right);
  if (node_right < left || right < node_left)
    return nil_;
  if (left <= node_left && node_right <= right)
    return index_.at(node);
  int middle = (node_left + node_right) / 2;
  int l = query(left, right, left_child(node), node_left, middle);
  int r = query(left, right, right_child(node), middle + 1, node_right);
  return value_.at(l) <= value_.at(r) ? l : r;
}

#include <bits/stdc++.h>
using namespace std;
int main() {
  int n, q;
  cin >> n >> q;
  RangeMinimumQuery rmq(n);
  for (int i = 0; i < q; ++i) {
    int com, x, y;
    cin >> com >> x >> y;
    if (com)
      cout << rmq.value(x, y) << endl;
    else
      rmq.update(x, y);
  }
}

Fixed submission:
// ???????????????
#include <cassert>
#include <climits>
#include <vector>
// ?????°
const int INF = INT_MAX;
// ?????????
class RangeMinimumQuery {
public:
  explicit RangeMinimumQuery(int s);
  void update(int i, int v);
  int index(int left, int right) const;
  int value(int left, int right) const;

private:
  int parent(int node) const;
  int left_child(int node) const;
  int right_child(int node) const;
  int power_of_two(int n) const;
  int query(int left, int right, int node, int node_left, int node_right) const;
  int size_, nil_, inf_;
  std::vector<int> index_, value_;
};
// ????????????
RangeMinimumQuery::RangeMinimumQuery(int s)
    : size_(power_of_two(s)), nil_(size_), inf_(INF),
      index_(2 * size_ - 1, nil_), value_(size_ + 1, inf_) {}
void RangeMinimumQuery::update(int i, int v) {
  int node = i + size_ - 1;
  index_.at(node) = i;
  value_.at(i) = v;
  while ((node = parent(node)) != nil_) {
    int l = value_.at(index_.at(left_child(node)));
    int r = value_.at(index_.at(right_child(node)));
    index_.at(node) = index_.at(l <= r ? left_child(node) : right_child(node));
  }
}
int RangeMinimumQuery::index(int left, int right) const {
  return query(left, right, 0, 0, size_ - 1);
}
int RangeMinimumQuery::value(int left, int right) const {
  return value_.at(query(left, right, 0, 0, size_ - 1));
}
int RangeMinimumQuery::parent(int node) const {
  return node ? (node - 1) / 2 : nil_;
}
int RangeMinimumQuery::left_child(int node) const { return 2 * node + 1; }
int RangeMinimumQuery::right_child(int node) const { return 2 * node + 2; }
int RangeMinimumQuery::power_of_two(int n) const {
  while (n & (n - 1))
    n += n & -n;
  return n;
}
int RangeMinimumQuery::query(int left, int right, int node, int node_left,
                             int node_right) const {
  assert(left <= right);
  assert(0 <= left);
  assert(right < size_);
  if (node_right < left || right < node_left)
    return nil_;
  if (left <= node_left && node_right <= right)
    return index_.at(node);
  int middle = (node_left + node_right) / 2;
  int l = query(left, right, left_child(node), node_left, middle);
  int r = query(left, right, right_child(node), middle + 1, node_right);
  return value_.at(l) <= value_.at(r) ? l : r;
}

#include <bits/stdc++.h>
using namespace std;
int main() {
  int n, q;
  cin >> n >> q;
  RangeMinimumQuery rmq(n);
  for (int i = 0; i < q; ++i) {
    int com, x, y;
    cin >> com >> x >> y;
    if (com)
      cout << rmq.value(x, y) << endl;
    else
      rmq.update(x, y);
  }
}