Problem p02852 (C++)

Buggy submission (status: Time Limit Exceeded):
#include "bits/stdc++.h"
#define REP(i, n) for (int i = 0; i < int(n); i++)
#define FOR(i, n, m) for (int i = int(n); i < int(m); i++)
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int INF = 1e9 + 6;
const ll LLINF = 1e18 + 1;

template <class Monoid> struct SegmentTree {
private:
  using Func = std::function<Monoid(Monoid, Monoid)>;
  Func F;
  Monoid UNITY;
  int n;
  std::vector<Monoid> node;

public:
  SegmentTree() {}

  // m=size, f=[](M a,M b){return ;}
  //  size : m
  SegmentTree(int m, const Func f, const Monoid &unity) { build(m, f, unity); }

  SegmentTree(const std::vector<Monoid> &v, const Func f, const Monoid &unity) {
    build(v, f, unity);
  }

  void build(int m, const Func f, const Monoid &unity) {
    F = f;
    UNITY = unity;
    n = 1;
    while (n < m)
      n <<= 1;
    node.resize(n * 2 - 1, UNITY);
  }

  void build(const std::vector<Monoid> &v, const Func f, const Monoid &unity) {
    F = f;
    UNITY = unity;
    int sz = v.size();
    n = 1;
    while (n < sz)
      n <<= 1;
    node.resize(n * 2 - 1, UNITY);
    REP(i, sz) node[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = F(node[2 * i + 1], node[2 * i + 2]);
  }

  void update(int x, Monoid val) {
    if (x >= n || x < 0)
      return;
    x += n - 1;
    node[x] = val;
    while (x > 0) {
      x = (x - 1) >> 1;
      node[x] = F(node[2 * x + 1], node[2 * x + 2]);
    }
  }
  // [a,b)
  Monoid get(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return UNITY;
    if (a <= l && r <= b)
      return node[k];
    Monoid vl = get(a, b, 2 * k + 1, l, (r - l) / 2 + l);
    Monoid vr = get(a, b, 2 * k + 2, (r - l) / 2 + l, r);
    return F(vl, vr);
  }

  Monoid operator[](int x) const { return node[n + x - 1]; }

  int size() { return n; }

  void print() {
    REP(i, n) { std::cout << i << "\t: " << node[n + i - 1] << std::endl; }
  }
};

int main() {
  int n, m;
  cin >> n >> m;
  string s;
  cin >> s;
  const int inf = 1e9 + 1;
  SegmentTree<int> seg(
      n + 1, [](int a, int b) { return min(a, b); }, inf);
  seg.update(n, 0);
  for (int i = n - 1; i >= 0; i--) {
    if (s[i] == '1')
      continue;
    int rm = seg.get(i + 1, min(n, i + m) + 1);
    if (rm == inf) {
      puts("-1");
      break;
    }
    seg.update(i, rm + 1);
  }
  int now = 0;
  while (now < n) {
    FOR(i, 1, m + 1) {
      if (seg[now] - 1 == seg[now + i]) {
        now += i;
        cout << i << " ";
        break;
      }
    }
  }
  cout << endl;
  return 0;
}

Fixed submission:
#include "bits/stdc++.h"
#define REP(i, n) for (int i = 0; i < int(n); i++)
#define FOR(i, n, m) for (int i = int(n); i < int(m); i++)
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int INF = 1e9 + 6;
const ll LLINF = 1e18 + 1;

template <class Monoid> struct SegmentTree {
private:
  using Func = std::function<Monoid(Monoid, Monoid)>;
  Func F;
  Monoid UNITY;
  int n;
  std::vector<Monoid> node;

public:
  SegmentTree() {}

  // m=size, f=[](M a,M b){return ;}
  //  size : m
  SegmentTree(int m, const Func f, const Monoid &unity) { build(m, f, unity); }

  SegmentTree(const std::vector<Monoid> &v, const Func f, const Monoid &unity) {
    build(v, f, unity);
  }

  void build(int m, const Func f, const Monoid &unity) {
    F = f;
    UNITY = unity;
    n = 1;
    while (n < m)
      n <<= 1;
    node.resize(n * 2 - 1, UNITY);
  }

  void build(const std::vector<Monoid> &v, const Func f, const Monoid &unity) {
    F = f;
    UNITY = unity;
    int sz = v.size();
    n = 1;
    while (n < sz)
      n <<= 1;
    node.resize(n * 2 - 1, UNITY);
    REP(i, sz) node[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = F(node[2 * i + 1], node[2 * i + 2]);
  }

  void update(int x, Monoid val) {
    if (x >= n || x < 0)
      return;
    x += n - 1;
    node[x] = val;
    while (x > 0) {
      x = (x - 1) >> 1;
      node[x] = F(node[2 * x + 1], node[2 * x + 2]);
    }
  }
  // [a,b)
  Monoid get(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return UNITY;
    if (a <= l && r <= b)
      return node[k];
    Monoid vl = get(a, b, 2 * k + 1, l, (r - l) / 2 + l);
    Monoid vr = get(a, b, 2 * k + 2, (r - l) / 2 + l, r);
    return F(vl, vr);
  }

  Monoid operator[](int x) const { return node[n + x - 1]; }

  int size() { return n; }

  void print() {
    REP(i, n) { std::cout << i << "\t: " << node[n + i - 1] << std::endl; }
  }
};

int main() {
  int n, m;
  cin >> n >> m;
  string s;
  cin >> s;
  const int inf = 1e9 + 1;
  SegmentTree<int> seg(
      n + 1, [](int a, int b) { return min(a, b); }, inf);
  seg.update(n, 0);
  for (int i = n - 1; i >= 0; i--) {
    if (s[i] == '1')
      continue;
    int rm = seg.get(i + 1, min(n, i + m) + 1);
    if (rm == inf) {
      puts("-1");
      return 0;
    }
    seg.update(i, rm + 1);
  }
  int now = 0;
  while (now < n) {
    FOR(i, 1, m + 1) {
      if (seg[now] - 1 == seg[now + i]) {
        now += i;
        cout << i << " ";
        break;
      }
    }
  }
  cout << endl;
  return 0;
}