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

#include <functional>
#include <iostream>
#include <queue>
#include <vector>
class SegmentTree {
  std::vector<std::vector<int>> _value_array;
  std::vector<std::vector<int>> _min_array;
  static constexpr int undefined = -1;
  static constexpr int initial_value = 2147483647;
  void ready_to_change_child_value(int depth, int pos) {
    if (depth >= _value_array.size())
      return;
    _min_array[depth][pos] = undefined;
    switch (_value_array[depth][pos]) {
    case undefined:
      return;
    default:
      _value_array[depth - 1][pos << 1] = _min_array[depth - 1][pos << 1] =
          _value_array[depth][pos];
      if (_value_array[depth - 1].size() > (pos << 1) + 1)
        _value_array[depth - 1][(pos << 1) + 1] =
            _min_array[depth - 1][(pos << 1) + 1] = _value_array[depth][pos];
      _value_array[depth][pos] = undefined;
    }
  }
  void apply_segment_value(int depth, int pos) {
    if (depth <= 0)
      return;
    switch (_value_array[depth][pos]) {
    case undefined:
      return;
    default:
      _value_array[depth - 1][pos << 1] = _min_array[depth - 1][pos << 1] =
          _value_array[depth][pos];
      if (_value_array[depth - 1].size() > (pos << 1) + 1)
        _value_array[depth - 1][(pos << 1) + 1] =
            _min_array[depth - 1][(pos << 1) + 1] = _value_array[depth][pos];
      _value_array[depth][pos] = undefined;
    }
  }
  void apply_change(int depth, int pos) {
    if (depth >= _min_array.size())
      return;
    if (_min_array[depth][pos] != undefined)
      return;
    _min_array[depth][pos] = _min_array[depth - 1][pos << 1];
    if (_min_array[depth - 1].size() > (pos << 1) + 1)
      _min_array[depth][pos] = std::min(_min_array[depth - 1][(pos << 1) + 1],
                                        _min_array[depth][pos]);
  }

public:
  SegmentTree(int size) : _value_array{}, _min_array{} {
    auto _size = std::vector<int>();
    for (auto i = size; i > 1; i = (i + 1) / 2) {
      _size.push_back(i);
    }
    _size.push_back(1);
    _value_array = std::vector<std::vector<int>>(_size.size());
    _min_array = std::vector<std::vector<int>>(_size.size());
    for (auto i = 0; i < _size.size(); ++i) {
      _value_array[i] = std::vector<int>(_size[i], initial_value);
      _min_array[i] = std::vector<int>(_size[i], initial_value);
    }
  }
  void update(const int from, const int to, const int new_value) {
    for (int depth = _value_array.size() - 1; depth >= 0; --depth) {
      if ((from - 1) >> depth == from >> depth)
        ready_to_change_child_value(depth, from >> depth);
      if (to >> depth == (to + 1) >> depth)
        ready_to_change_child_value(depth, to >> depth);
    }
    int left{from}, right{to};
    for (auto depth = 0; left <= right; ++depth) {
      if (left % 2 == 1) {
        _value_array[depth][left] = _min_array[depth][left] = new_value;
        ++left;
      }
      if (right % 2 == 0) {
        _value_array[depth][right] = _min_array[depth][right] = new_value;
        --right;
      }
      left >>= 1;
      right >>= 1;
    }
    for (auto depth = 1; depth < _min_array.size(); ++depth) {
      if ((from - 1) >> depth == from >> depth) {
        apply_change(depth, from >> depth);
      }
      if (to >> depth == (to + 1) >> depth) {
        apply_change(depth, to >> depth);
      }
    }
  }
  int find(const int from, const int to) {
    for (int depth = _min_array.size() - 1; depth >= 0; --depth) {
      if ((from - 1) >> depth == from >> depth)
        apply_segment_value(depth, from >> depth);
      if (to >> depth == (to + 1) >> depth)
        apply_segment_value(depth, to >> depth);
    }
    int min = initial_value;
    int left{from}, right{to};
    for (auto depth = 0; left <= right; ++depth) {
      if (left % 2 == 1) {
        min = std::min(min, _min_array[depth][left]);
        ++left;
      }
      if (right % 2 == 0) {
        min = std::min(min, _min_array[depth][right]);
        --right;
      }
      left >>= 1;
      right >>= 1;
    }
    return min;
  }
};
int main() {
  int n, q;
  std::cin >> n >> q;
  SegmentTree seg(n);
  int query, s, t, x;
  for (auto i = 0; i < q; ++i) {
    std::cin >> query;
    switch (query) {
    case 0:
      std::cin >> s >> t >> x;
      seg.update(s, t, x);
      break;
    default:
      std::cin >> s >> t;
      std::cout << seg.find(s, t) << std::endl;
    }
  }
}


Error: 0

Fixed submission:

#include <functional>
#include <iostream>
#include <queue>
#include <vector>
class SegmentTree {
  std::vector<std::vector<int>> _value_array;
  std::vector<std::vector<int>> _min_array;
  static constexpr int undefined = -1;
  static constexpr int initial_value = 2147483647;
  void solve_defined_value(int depth, int pos) {
    if (depth >= _value_array.size())
      return;
    switch (_value_array[depth][pos]) {
    case undefined:
      return;
    default:
      _value_array[depth - 1][pos << 1] = _min_array[depth - 1][pos << 1] =
          _value_array[depth][pos];
      if (_value_array[depth - 1].size() > (pos << 1) + 1)
        _value_array[depth - 1][(pos << 1) + 1] =
            _min_array[depth - 1][pos << 1] = _value_array[depth][pos];
      _value_array[depth][pos] = undefined;
      _min_array[depth][pos] = undefined;
    }
  }
  void solve_defined_min(int depth, int pos) {
    if (depth >= _min_array.size() || _min_array[depth][pos] != undefined)
      return;
    if (_min_array[depth - 1].size() > (pos << 1) + 1) {
      _min_array[depth][pos] = std::min(_min_array[depth - 1][pos << 1],
                                        _min_array[depth - 1][(pos << 1) + 1]);
    } else {
      _min_array[depth][pos] = _min_array[depth - 1][pos << 1];
    }
  }

public:
  SegmentTree(int size) : _value_array{}, _min_array{} {
    auto _size = std::vector<int>();
    for (auto i = size; i > 1; i = (i + 1) / 2) {
      _size.push_back(i);
    }
    _size.push_back(1);
    _value_array = std::vector<std::vector<int>>(_size.size());
    _min_array = std::vector<std::vector<int>>(_size.size());
    for (auto i = 0; i < _size.size(); ++i) {
      _value_array[i] = std::vector<int>(_size[i], initial_value);
      _min_array[i] = std::vector<int>(_size[i], initial_value);
    }
  }
  void update(int from, int to, int new_value) {
    int left{from}, right{to};
    for (auto depth = _value_array.size() - 1; left <= right; --depth) {
      if ((left - 1) >> depth == left >> depth) {
        solve_defined_value(depth, left >> depth);
      }
      if (right >> depth == (right + 1) >> depth) {
        solve_defined_value(depth, right >> depth);
      }
      if (((left - 1) >> depth != left >> depth) &&
          (left >> depth != (right + 1) >> depth)) {
        _value_array[depth][left >> depth] = new_value;
        _min_array[depth][left >> depth] = new_value;
        left = ((left >> depth) + 1) << depth;
      }
      if (((left - 1) >> depth != right >> depth) &&
          (right >> depth != (right + 1) >> depth)) {
        _value_array[depth][right >> depth] = new_value;
        _min_array[depth][right >> depth] = new_value;
        right = ((right >> depth) - 1) << depth;
      }
    }
    for (auto depth = 1; depth < _min_array.size(); ++depth) {
      if (from >> depth == (from - 1) >> depth) {
        solve_defined_min(depth, from >> depth);
      }
      if ((to >> depth == (to + 1) >> depth) &&
          ((from - 1) >> depth != to >> depth)) {
        solve_defined_min(depth, to >> depth);
      }
    }
  }
  int find(int from, int to) const {
    int min = initial_value;
    for (auto depth = _min_array.size() - 1; from <= to; --depth) {
      if ((from - 1) >> depth != from >> depth &&
          from >> depth != (to + 1) >> depth) {
        min = std::min(min, _min_array[depth][from >> depth]);
        from = ((from >> depth) + 1) << depth;
      }
      if ((from - 1) >> depth != to >> depth &&
          to >> depth != (to + 1) >> depth) {
        min = std::min(min, _min_array[depth][to >> depth]);
        to = ((to >> depth) - 1) << depth;
      }
    }
    return min;
  }
};
int main() {
  int n, q;
  std::cin >> n >> q;
  SegmentTree seg(n);
  int query, s, t, x;
  for (auto i = 0; i < q; ++i) {
    std::cin >> query;
    switch (query) {
    case 0:
      std::cin >> s >> t >> x;
      seg.update(s, t, x);
      break;
    default:
      std::cin >> s >> t;
      std::cout << seg.find(s, t) << std::endl;
    }
  }
}