Problem p02345 (C++) — buggy submission, verdict: Runtime Error

#include <climits>
const int INF = INT_MAX;

#include <vector>
template <typename T> class LazyPropagationSegmentTree {
public:
  LazyPropagationSegmentTree(int n) : size_(1) {
    while (size_ < n)
      size_ <<= 1;
    node_.assign(size_ << 1, INF);
    lazy_.assign(size_ << 1, 0);
  }
  T find(int left, int right) { return find(left, right + 1, 1, 0, size_); }
  void add(int left, int right, T value) {
    add(left, right + 1, value, 1, 0, size_);
  }
  void set(int i, T value) { set(i, i + 1, value, 1, 0, size_); }

private:
  int left_child(int node) const { return node << 1; }
  int right_child(int node) const { return (node << 1) + 1; }
  T find(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a)
      return INF;
    if (a <= l && r <= b)
      return node_.at(k) + lazy_.at(k);
    lazy_.at(left_child(k)) += lazy_.at(k);
    lazy_.at(right_child(k)) += lazy_.at(k);
    lazy_.at(k) = 0;
    auto vl = find(a, b, left_child(k), l, (l + r) / 2);
    auto vr = find(a, b, right_child(k), (l + r) / 2, r);
    return std::min(vl, vr);
  }
  T add(int a, int b, T value, int k, int l, int r) {
    if (b <= l || r <= a)
      return node_.at(k) + lazy_.at(k);
    if (a <= l && r <= b)
      return node_.at(k) + (lazy_.at(k) += value);
    lazy_.at(left_child(k)) += lazy_.at(k);
    lazy_.at(right_child(k)) += lazy_.at(k);
    lazy_.at(k) = 0;
    auto vl = add(a, b, value, left_child(k), l, (l + r) / 2);
    auto vr = add(a, b, value, right_child(k), (l + r) / 2, r);
    return node_.at(k) = std::min(vl, vr);
  }
  T set(int a, int b, T value, int k, int l, int r) {
    if (b <= l || r <= a)
      return node_.at(k) + lazy_.at(k);
    if (a <= l && r <= b) {
      lazy_.at(k) = 0;
      return node_.at(k) = value;
    }
    lazy_.at(left_child(k)) += lazy_.at(k);
    lazy_.at(right_child(k)) += lazy_.at(k);
    lazy_.at(k) = 0;
    auto vl = set(a, b, value, left_child(k), l, (l + r) / 2);
    auto vr = set(a, b, value, right_child(k), (l + r) / 2, r);
    return node_.at(k) = std::min(vl, vr);
  }
  int size_;
  std::vector<T> node_;
  std::vector<T> lazy_;
};

#include <iostream>
using namespace std;
int main() {
  int n, q;
  cin >> n >> q;
  LazyPropagationSegmentTree<long long> RMQ(n);
  while (0 < q--) {
    int com, x, y;
    cin >> com >> x >> y;
    if (com)
      cout << RMQ.find(x, y) << endl;
    else
      RMQ.set(x, y);
  }
}

Error: -6
terminate called after throwing an instance of 'std::bad_function_call'
  what():  bad_function_call


Fixed submission:

#include <algorithm>
#include <climits>
#include <functional>
#include <vector>
template <typename T = int, T LOWEST = INT_MAX,
          typename F = std::function<T(T, T)>>
class SegmentTree {
public:
  explicit SegmentTree(int n,
                       const F &op_ = (const int &(*)(const int &,
                                                      const int &))std::min)
      : NIL(-1) {
    initialize(n);
  }
  explicit SegmentTree(const std::vector<T> &list,
                       const F &op_ = (const int &(*)(const int &,
                                                      const int &))std::min)
      : NIL(-1) {
    initialize(list.size());
    for (int i = 0; i < list.size(); ++i)
      update(i, list.at(i));
  }
  const T find(int left, int right) const {
    return query(left, right + 1, 0, 0, size_);
  }
  void update(int index, const T &value) {
    int i = index + size_ - 1;
    node_.at(i) = value;
    while ((i = parent(i)) != NIL)
      node_.at(i) = op_(node_.at(left_child(i)), node_.at(right_child(i)));
  }

private:
  void initialize(int n) {
    size_ = 1;
    while (size_ < n)
      size_ <<= 1;
    node_.assign((size_ << 1) - 1, LOWEST);
  }
  int parent(int node) const { return node == 0 ? NIL : (node - 1) >> 1; }
  int left_child(int node) const { return (node << 1) + 1; }
  int right_child(int node) const { return (node << 1) + 2; }
  const T query(int a, int b, int k, int l, int r) const {
    if (b <= l || r <= a)
      return LOWEST;
    if (a <= l && r <= b)
      return node_.at(k);
    auto vl = query(a, b, left_child(k), l, (l + r) / 2);
    auto vr = query(a, b, right_child(k), (l + r) / 2, r);
    return op_(vl, vr);
  }
  const int NIL;
  int size_;
  std::vector<T> node_;
  F op_;
};

#include <iostream>
using namespace std;
int main() {
  int n, q;
  cin >> n >> q;
  SegmentTree<int> RMQ(n);
  for (int i = 0; i < q; ++i) {
    int com, x, y;
    cin >> com >> x >> y;
    if (com)
      cout << RMQ.find(x, y) << endl;
    else
      RMQ.update(x, y);
  }
}