int n, k, b, tot; int a[kMaxN], f[kMaxN], ans[kMaxN]; int bel[kMaxN], L[kMaxT], R[kMaxT], val[kMaxN], cntu[kMaxT], tag[kMaxT], unq[kMaxT][kMaxB], cnt[kMaxT][kMaxB]; int pos[kMaxT];
voidprework(){ // b = round(sqrtl(n * std::__lg(n))); b = std::min(n, 150); tot = (n + b - 1) / b; for (int i = 1; i <= tot; ++i) { L[i] = (i - 1) * b + 1, R[i] = std::min(i * b, n); pos[i] = cntu[i] = 1, unq[i][1] = 0, cnt[i][1] = R[i] - L[i] + 1; for (int j = L[i]; j <= R[i]; ++j) bel[j] = i; } }
voidrebuild(int x, int v){ staticint unq[kMaxN * 2], cnt[kMaxN * 2] = {0}; staticint unq1[kMaxN * 2], unq2[kMaxN * 2] = {0}; staticbool vis[kMaxN * 2]; int mm = cntu[x]; int m1 = 0, m2 = 0; for (int i = L[x]; i <= R[x]; ++i) ++cnt[val[i] += tag[x]]; for (int i = 1; i <= mm; ++i) { unq[i] = ::unq[x][i] + tag[x]; int vv = unq[i] + v; if (!vis[unq[i]] && cnt[unq[i]]) unq1[++m1] = unq[i], vis[unq[i]] = 1; if (vv >= 0 && !vis[vv] && cnt[vv]) unq2[++m2] = vv, vis[vv] = 1; } // for (int i = 1; i <= mm; ++i) // if (unq[i] + v >= 0 && cnt[unq[i] + v] && !vis[unq[i] + v]) // unq2[++m2] = unq[i] + v; // for (int i = 1; i <= m1; ++i) assert(cnt[unq1[i]]); // for (int i = 1; i <= m2; ++i) assert(!vis[unq2[i]]); // for (int i = 1; i <= mm; ++i) vis[unq[i]] = 0; cntu[x] = tag[x] = 0; for (int i = 1, j = 1; i <= m1 || j <= m2;) { int v = 0; if (i <= m1 && (j > m2 || unq1[i] < unq2[j])) v = unq1[i], ++i; else v = unq2[j], ++j; // assert(cnt[v]); ::unq[x][++cntu[x]] = v; ::cnt[x][cntu[x]] = ::cnt[x][cntu[x] - 1] + cnt[v]; vis[v] = cnt[v] = 0; } // for (int i = L[x]; i <= R[x]; ++i) assert(!cnt[val[i]]); // int i = 1, j = 1; // for (; j <= mm && unq[j] + v < 0; ++j) {} // for (; i <= mm || j <= mm;) { // for (; i <= mm && !cnt[unq[i]]; ++i) {} // for (; j <= mm && !cnt[unq[j] + v]; ++j) {} // int v1 = unq[i], v2 = unq[j] + v; // if (i <= mm && (j > mm || v1 <= v2)) { // ::unq[x][++cntu[x]] = v1; // ::cnt[x][cntu[x]] = ::cnt[x][cntu[x] - 1] + cnt[v1]; // cnt[v1] = 0; // } else if (v2 >= 0 && cnt[v2]) { // ::unq[x][++cntu[x]] = v2; // ::cnt[x][cntu[x]] = ::cnt[x][cntu[x] - 1] + cnt[v2]; // cnt[v2] = 0; // } // } // int mm = 0; // for (int i = L[x]; i <= R[x]; ++i) { // ++cnt[val[i] += tag[x]]; // unq[++mm] = val[i]; // } // std::sort(unq + 1, unq + 1 + mm); // mm = std::unique(unq + 1, unq + 1 + mm) - (unq + 1); // cntu[x] = mm, tag[x] = 0; // for (int i = 1; i <= mm; ++i) { // ::unq[x][i] = unq[i]; // ::cnt[x][i] = ::cnt[x][i - 1] + cnt[unq[i]]; // cnt[unq[i]] = 0; // } pos[x] = 0; for (; pos[x] < cntu[x] && ::unq[x][pos[x] + 1] <= k; ++pos[x]) {} // for (int i = L[x]; i <= R[x]; ++i) assert(!cnt[val[i]]); }
voidupdate(int l, int r, int v){ if (l > r) return; int x = bel[l], y = bel[r]; if (x == y) { for (int i = l; i <= r; ++i) val[i] += v; rebuild(x, v); } else { for (int i = x + 1; i < y; ++i) { tag[i] += v; for (; pos[i] < cntu[i] && unq[i][pos[i] + 1] + tag[i] <= k; ++pos[i]) {} for (; pos[i] && unq[i][pos[i]] + tag[i] > k; --pos[i]) {} } for (int i = l; i <= R[x]; ++i) val[i] += v; for (int i = L[y]; i <= r; ++i) val[i] += v; rebuild(x, v), rebuild(y, v); } }
intquery(int i){ return val[i] + tag[bel[i]]; }
intquery(int l, int v){ int ret = 0, x = bel[l]; // for (int i = l; i <= n; ++i) ret += (query(i) <= v); for (int i = l; i <= R[x]; ++i) ret += (val[i] + tag[x] <= v); // for (int i = x + 1; i <= tot; ++i) ret += cnt[i][std::upper_bound(unq[i] + 1, unq[i] + 1 + cntu[i], v - tag[i]) - unq[i] - 1]; for (int i = x + 1; i <= tot; ++i) ret += cnt[i][pos[i]]; return ret; }
voiddickdreamer(){ std::cin >> n >> k; for (int i = 1; i < n; ++i) std::cin >> a[i]; a[n] = n + 1; std::fill_n(f + 1, n, k + 1); prework(); for (int i = n; i; --i) { // f[i] = 0; // for (int j = i + 1; j < a[i]; ++j) ++f[j]; update(i + 1, a[i] - 1, 1); update(a[i], n, 1 - query(a[i])); ans[i] = query(i, k); // for (int j = n; j >= a[i]; --j) f[j] -= f[a[i]] - 1; // for (int j = i; j <= n; ++j) ans[i] += (f[j] <= k); } for (int i = 1; i <= n; ++i) std::cout << ans[i] << ' '; }