Language: C++

#include<iostream>
#include<iomanip>
#include<map>
#include<unordered_map>
#include<set>
#include<unordered_set>
#include<vector>
#include<array>
#include<string>
#include<stack>
#include<queue>
#include<algorithm>
#include<cassert>
#include<functional>
#include<random>
#include<complex>
#include<bitset>
#include<cstdint>
#include<chrono>
#define int int64_t
#define uint uint64_t
#define REP(i, a, b) for (int64_t i = (int64_t)(a); i < (int64_t)(b); i++)
#define rep(i, a) REP(i, 0, a)
#define EACH(i, a) for (auto i: a)
#define ITR(x, a) for (auto x = a.begin(); x != a.end(); x++)
#define ALL(a) (a.begin()), (a.end())
#define HAS(a, x) (a.find(x) != a.end())
#define Min(x) *min_element(ALL(x))
#define Max(x) *max_element(ALL(x))
#define Unique(L) (L.erase(unique(ALL(L)), L.end()))
#define veccat(v1, v2) std::copy((v2).begin(),(v2).end(),std::back_inserter(v1)/*v1の後ろにv2を入れる*/)
#define intmax (std::numeric_limits<int64_t>::max() / 4)
using namespace std;
//typedef boost::multiprecision::cpp_int bigint;
const double EPS = 1e-9;
const double PI = acos(-1.0);

using namespace std;


class segtree_min_pointupdate {
private:
	typedef int T;
	const static T INF = (1LL << 61);
public:
	segtree_min_pointupdate(const int N) {
		SIZE = roundup_pow2(N);
		v.clear();
		v.resize(SIZE * 2, INF);
	}

	//v[index]=numberとする。
	void update(const int index, const T number) {
		v[index + SIZE] = number;
		for (int i = (index + SIZE) / 2; i; i = i / 2)v[i] = min(v[i * 2], v[i * 2 + 1]);
	}

	//[index]の値を返す。
	T getnum(const int index) {
		return v[index + SIZE];
	}

	//[L,R)の最小値を返す。
	T getmin(const int L, const int R) {
		return getmin_inner(L, R, 1, 0, SIZE);
	}
private:
	T getmin_inner(const int queryL, const int queryR, const int index, const int segL, const int segR) {
		if (queryR <= segL || segR <= queryL)return INF;
		if (queryL <= segL && segR <= queryR)return v[index];
		return min(getmin_inner(queryL, queryR, index * 2, segL, (segL + segR) / 2),
			getmin_inner(queryL, queryR, index * 2 + 1, (segL + segR) / 2, segR));
	}

	//x以上であるような2のべき乗数のうち最小のものを返す。
	int roundup_pow2(int x) {
		x--;
		rep(i, 6)x |= x >> (1LL << i);
		return x + 1;
	}

	int SIZE;
	vector<T>v;
};


signed main() {

	int N, M;
	cin >> N >> M;
	string S;
	cin >> S;

	//seg[i]:=(マスiからゴールまでの最短手数)*(N+1)+i
	segtree_min_pointupdate seg(N + M + 1);

	//dp[i]:=マスiからゴールまでの最短手数と、そのために次に踏むべき最も小さいマス
	vector<pair<int,int>>dp(N + 1, make_pair(0,0));

	seg.update(N, N);

	for (int i = N - 1; i >= 0; --i) {
		if (S[i] == '1') {
			dp[i] = make_pair(-1, -1);
			continue;
		}

		int res = seg.getmin(i + 1, i + M + 1);


		int tekazu = (res / (N + 1)) + 1;
		int next = res % (N + 1);

		if (tekazu > N) {
			dp[i] = make_pair(-1, -1);
			continue;
		}


		dp[i] = make_pair(tekazu, next);
		seg.update(i, tekazu * (N + 1) + i);
	}

	if (dp[0].first == -1) {
		cout << -1 << endl;
		return 0;
	}

	for (int ans = 0; ans < N;) {
		if (ans)cout << " ";
		cout << dp[ans].second - ans;
		ans = dp[ans].second;
	}
	cout << endl;

	return 0;
}

Compiler output:
/usr/bin/ld: /tmp/cci9Skpp.o: warning: relocation against `_ZN23segtree_min_pointupdate3INFE' in read-only section `.text._ZN23segtree_min_pointupdateC2El[_ZN23segtree_min_pointupdateC5El]'
/usr/bin/ld: /tmp/cci9Skpp.o: in function `segtree_min_pointupdate::segtree_min_pointupdate(long)':
a.cc:(.text._ZN23segtree_min_pointupdateC2El[_ZN23segtree_min_pointupdateC5El]+0x63): undefined reference to `segtree_min_pointupdate::INF'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status