Problem p02852 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <vector>
using namespace std;
using ll = long long;
#define fst first
#define snd second

/* clang-format off */
template <class T, size_t D> struct _vec { using type = vector<typename _vec<T, D - 1>::type>; };
template <class T> struct _vec<T, 0> { using type = T; };
template <class T, size_t D> using vec = typename _vec<T, D>::type;
template <class T> vector<T> make_v(size_t size, const T& init) { return vector<T>(size, init); }
template <class... Ts> auto make_v(size_t size, Ts... rest) { return vector<decltype(make_v(rest...))>(size, make_v(rest...)); }
template <class T> inline void chmin(T &a, const T& b) { if (b < a) a = b; }
template <class T> inline void chmax(T &a, const T& b) { if (b > a) a = b; }
/* clang-format on */

template <typename ValueMonoid, typename OperatorMonoid> class LazySegmentTree {
public:
  using value_type = ValueMonoid;
  using reference = value_type &;
  using const_reference = const value_type &;
  using operator_type = OperatorMonoid;

private:
  using operator_constref = const operator_type &;
  using container_type = std::vector<std::pair<value_type, operator_type>>;

public:
  using size_type = typename container_type::size_type;

private:
  using F = std::function<value_type(const_reference, const_reference)>;
  using G = std::function<operator_type(operator_constref, operator_constref)>;
  using H = std::function<value_type(const_reference, operator_constref)>;
  const F f;
  const G g;
  const H h;
  const value_type v_neutral;
  const operator_type o_neutral;
  size_type height, size_;
  container_type tree;
  static size_type getheight(const size_type size) {
    size_type ret = 0;
    while ((size_type)1 << ret < size)
      ++ret;
    return ret;
  }
  value_type reflect(const size_type index) {
    return h(tree[index].first, tree[index].second);
  }
  void recalc(const size_type index) {
    tree[index].first = f(reflect(index << 1), reflect(index << 1 | 1));
  }
  void assign(const size_type index, operator_constref data) {
    tree[index].second = g(tree[index].second, data);
  }
  void push(const size_type index) {
    assign(index << 1, tree[index].second);
    assign(index << 1 | 1, tree[index].second);
    tree[index].second = o_neutral;
  }
  void propagate(const size_type index) {
    for (size_type i = height; i; --i)
      push(index >> i);
  }
  void thrust(const size_type index) {
    tree[index].first = reflect(index);
    push(index);
  }
  void evaluate(const size_type index) {
    for (size_type i = height; i; --i)
      thrust(index >> i);
  }
  void build(size_type index) {
    while (index >>= 1)
      recalc(index);
  }

public:
  LazySegmentTree(
      const size_type size, const F &value_addition = std::plus<value_type>(),
      const_reference value_neutral = value_type(),
      const G &operator_multiplication = std::multiplies<operator_type>(),
      operator_constref operator_neutral = operator_type(),
      const H &mutual_multiplication =
          [](const_reference l, operator_constref r) { return l * r; })
      : f(value_addition), v_neutral(value_neutral), g(operator_multiplication),
        o_neutral(operator_neutral), h(mutual_multiplication),
        height(getheight(size)), size_((size_type)1 << height),
        tree(size_ << 1, std::make_pair(v_neutral, o_neutral)) {}
  void update(size_type begin, size_type end, operator_constref data) {
    assert(begin <= end);
    assert(begin <= size_);
    assert(end <= size_);
    begin += size_;
    end += size_;
    propagate(begin);
    propagate(end - 1);
    for (size_type left = begin, right = end; left < right;
         left >>= 1, right >>= 1) {
      if (left & 1)
        assign(left++, data);
      if (right & 1)
        assign(right - 1, data);
    }
    build(begin);
    build(end - 1);
  }
  void update(size_type index,
              const std::function<value_type(const_reference)> &e) {
    assert(index < size_);
    index += size_;
    propagate(index);
    tree[index].first = e(reflect(index));
    tree[index].second = o_neutral;
    build(index);
  }
  void update(const size_type index, const_reference data) {
    assert(index < size_);
    update(index, [&data](const_reference d) { return data; });
  }
  value_type range(size_type begin, size_type end) {
    assert(begin <= end);
    assert(begin <= size_);
    assert(end <= size_);
    begin += size_;
    end += size_;
    evaluate(begin);
    evaluate(end - 1);
    value_type retL = v_neutral, retR = v_neutral;
    for (; begin < end; begin >>= 1, end >>= 1) {
      if (begin & 1)
        retL = f(retL, reflect(begin++));
      if (end & 1)
        retR = f(reflect(end - 1), retR);
    }
    return f(retL, retR);
  }
  size_type search(const std::function<bool(const_reference)> &b) {
    if (!b(reflect(1)))
      return size_;
    value_type acc = v_neutral;
    size_type i = 1;
    while (i < size_) {
      thrust(i);
      if (!b(f(acc, reflect(i <<= 1))))
        acc = f(acc, reflect(i++));
    }
    return i - size_;
  }
  const_reference operator[](const size_type index) {
    assert(index < size_);
    index += size_;
    evaluate(index);
    tree[index].first = reflect(index);
    tree[index].second = o_neutral;
    return tree[index].first;
  }
  size_type size() const { return size_; }
};

using value_t = pair<int, int>;

const value_t inf = {1 << 25, -1};

int main() {
#ifdef DEBUG
  ifstream ifs("in.txt");
  cin.rdbuf(ifs.rdbuf());
#endif
  int N, M;
  string S;
  while (cin >> N >> M >> S) {
    LazySegmentTree<value_t, value_t> seg(
        N, [&](const value_t &a, const value_t &b) { return min(a, b); }, inf,
        [&](const value_t &a, const value_t &b) { return min(a, b); }, inf,
        [&](const value_t &a, const value_t &b) { return min(a, b); });
    seg.update(N, {0, -1});
    for (int i = N; i >= 1; i--) {
      if (S[i] == '1')
        continue;
      auto v = seg.range(i, i + 1);
      auto nv = value_t{v.fst + 1, i};
      seg.update(max(i - M, 0), i, nv);
    }
    auto v = seg.range(0, 1);
    if (v >= inf) {
      cout << -1 << endl;
      break;
    }
    int i = 0;
    vector<int> res;
    while (i < N) {
      auto v = seg.range(i, i + 1);
      int jump = (v.snd - i);
      res.push_back(jump);
      i = v.snd;
    }
    for (int x : res)
      cout << x << " ";
    cout << endl;
  }
  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <vector>
using namespace std;
using ll = long long;
#define fst first
#define snd second

/* clang-format off */
template <class T, size_t D> struct _vec { using type = vector<typename _vec<T, D - 1>::type>; };
template <class T> struct _vec<T, 0> { using type = T; };
template <class T, size_t D> using vec = typename _vec<T, D>::type;
template <class T> vector<T> make_v(size_t size, const T& init) { return vector<T>(size, init); }
template <class... Ts> auto make_v(size_t size, Ts... rest) { return vector<decltype(make_v(rest...))>(size, make_v(rest...)); }
template <class T> inline void chmin(T &a, const T& b) { if (b < a) a = b; }
template <class T> inline void chmax(T &a, const T& b) { if (b > a) a = b; }
/* clang-format on */

template <typename ValueMonoid, typename OperatorMonoid> class LazySegmentTree {
public:
  using value_type = ValueMonoid;
  using reference = value_type &;
  using const_reference = const value_type &;
  using operator_type = OperatorMonoid;

private:
  using operator_constref = const operator_type &;
  using container_type = std::vector<std::pair<value_type, operator_type>>;

public:
  using size_type = typename container_type::size_type;

private:
  using F = std::function<value_type(const_reference, const_reference)>;
  using G = std::function<operator_type(operator_constref, operator_constref)>;
  using H = std::function<value_type(const_reference, operator_constref)>;
  const F f;
  const G g;
  const H h;
  const value_type v_neutral;
  const operator_type o_neutral;
  size_type height, size_;
  container_type tree;
  static size_type getheight(const size_type size) {
    size_type ret = 0;
    while ((size_type)1 << ret < size)
      ++ret;
    return ret;
  }
  value_type reflect(const size_type index) {
    return h(tree[index].first, tree[index].second);
  }
  void recalc(const size_type index) {
    tree[index].first = f(reflect(index << 1), reflect(index << 1 | 1));
  }
  void assign(const size_type index, operator_constref data) {
    tree[index].second = g(tree[index].second, data);
  }
  void push(const size_type index) {
    assign(index << 1, tree[index].second);
    assign(index << 1 | 1, tree[index].second);
    tree[index].second = o_neutral;
  }
  void propagate(const size_type index) {
    for (size_type i = height; i; --i)
      push(index >> i);
  }
  void thrust(const size_type index) {
    tree[index].first = reflect(index);
    push(index);
  }
  void evaluate(const size_type index) {
    for (size_type i = height; i; --i)
      thrust(index >> i);
  }
  void build(size_type index) {
    while (index >>= 1)
      recalc(index);
  }

public:
  LazySegmentTree(
      const size_type size, const F &value_addition = std::plus<value_type>(),
      const_reference value_neutral = value_type(),
      const G &operator_multiplication = std::multiplies<operator_type>(),
      operator_constref operator_neutral = operator_type(),
      const H &mutual_multiplication =
          [](const_reference l, operator_constref r) { return l * r; })
      : f(value_addition), v_neutral(value_neutral), g(operator_multiplication),
        o_neutral(operator_neutral), h(mutual_multiplication),
        height(getheight(size)), size_((size_type)1 << height),
        tree(size_ << 1, std::make_pair(v_neutral, o_neutral)) {}
  void update(size_type begin, size_type end, operator_constref data) {
    assert(begin <= end);
    assert(begin <= size_);
    assert(end <= size_);
    begin += size_;
    end += size_;
    propagate(begin);
    propagate(end - 1);
    for (size_type left = begin, right = end; left < right;
         left >>= 1, right >>= 1) {
      if (left & 1)
        assign(left++, data);
      if (right & 1)
        assign(right - 1, data);
    }
    build(begin);
    build(end - 1);
  }
  void update(size_type index,
              const std::function<value_type(const_reference)> &e) {
    assert(index < size_);
    index += size_;
    propagate(index);
    tree[index].first = e(reflect(index));
    tree[index].second = o_neutral;
    build(index);
  }
  void update(const size_type index, const_reference data) {
    assert(index < size_);
    update(index, [&data](const_reference d) { return data; });
  }
  value_type range(size_type begin, size_type end) {
    assert(begin <= end);
    assert(begin <= size_);
    assert(end <= size_);
    begin += size_;
    end += size_;
    evaluate(begin);
    evaluate(end - 1);
    value_type retL = v_neutral, retR = v_neutral;
    for (; begin < end; begin >>= 1, end >>= 1) {
      if (begin & 1)
        retL = f(retL, reflect(begin++));
      if (end & 1)
        retR = f(reflect(end - 1), retR);
    }
    return f(retL, retR);
  }
  size_type search(const std::function<bool(const_reference)> &b) {
    if (!b(reflect(1)))
      return size_;
    value_type acc = v_neutral;
    size_type i = 1;
    while (i < size_) {
      thrust(i);
      if (!b(f(acc, reflect(i <<= 1))))
        acc = f(acc, reflect(i++));
    }
    return i - size_;
  }
  const_reference operator[](const size_type index) {
    assert(index < size_);
    index += size_;
    evaluate(index);
    tree[index].first = reflect(index);
    tree[index].second = o_neutral;
    return tree[index].first;
  }
  size_type size() const { return size_; }
};

using value_t = pair<int, int>;

const value_t inf = {1 << 25, -1};

int main() {
#ifdef DEBUG
  ifstream ifs("in.txt");
  cin.rdbuf(ifs.rdbuf());
#endif
  int N, M;
  string S;
  while (cin >> N >> M >> S) {
    LazySegmentTree<value_t, value_t> seg(
        N + 1, [&](const value_t &a, const value_t &b) { return min(a, b); },
        inf, [&](const value_t &a, const value_t &b) { return min(a, b); }, inf,
        [&](const value_t &a, const value_t &b) { return min(a, b); });
    seg.update(N, {0, -1});
    for (int i = N; i >= 1; i--) {
      if (S[i] == '1')
        continue;
      auto v = seg.range(i, i + 1);
      auto nv = value_t{v.fst + 1, i};
      seg.update(max(i - M, 0), i, nv);
    }
    auto v = seg.range(0, 1);
    if (v >= inf) {
      cout << -1 << endl;
      break;
    }
    int i = 0;
    vector<int> res;
    while (i < N) {
      auto v = seg.range(i, i + 1);
      int jump = (v.snd - i);
      res.push_back(jump);
      i = v.snd;
    }
    for (int x : res)
      cout << x << " ";
    cout << endl;
  }
  return 0;
}