考虑扫描序列时动态维护函数 ff,注意到 f(x)f(x+1)f(x) \le f(x + 1),容易用线段树维护。

#include <bits/stdc++.h>
using namespace std;
const int D = (1 << 17) - 1;
const int N = 2.7e5 + 12;
int a[N], amax[N], b[N];
void reset(int n, int ll, int rr, int b)
{
	a[b] = 0;
	amax[b] = 0;
	if (n < ll) return;
	if (ll == rr) return;
	int mid = (ll + rr) >> 1;
	reset(n, ll, mid, b + b);
	reset(n, mid + 1, rr, b + b + 1);
}
void add(int l, int r, int ll, int rr, int b)
{
	if (r < 0) return;
	if (l == ll && r == rr)
	{
		a[b]++;
		amax[b]++;
		return;
	}
	if (a[b])
	{
		a[b + b] += a[b];
		amax[b + b] += a[b];
		a[b + b + 1] += a[b];
		amax[b + b + 1] += a[b];
		a[b] = 0;
	}
	int mid = (ll + rr) >> 1;
	int cl = min(r, mid);
	int cr = max(l, mid + 1);
	if (l <= mid) add(l, cl, ll, mid, b + b);
	if (r > mid) add(cr, r, mid + 1, rr, b + b + 1);
	amax[b] = max(amax[b + b], amax[b + b + 1]);
}
int get(int l, int r, int ll, int rr, int b)
{
	if (l == ll && r == rr) return amax[b];
	if (a[b])
	{
		a[b + b] += a[b];
		amax[b + b] += a[b];
		a[b + b + 1] += a[b];
		amax[b + b + 1] += a[b];
		a[b] = 0;
	}
	int mid = (ll + rr) >> 1;
	int ans = 0;
	int cl = min(r, mid);
	int cr = max(l, mid + 1);
	if (l <= mid) ans = max(ans, get(l, cl, ll, mid, b + b));
	if (r > mid) ans = max(ans, get(cr, r, mid + 1, rr, b + b + 1));
	return ans;
}
int find(int x, int ll, int rr, int b)
{
	if (amax[b] <= x) return rr;
	if (ll == rr) return -1;
	if (a[b])
	{
		a[b + b] += a[b];
		amax[b + b] += a[b];
		a[b + b + 1] += a[b];
		amax[b + b + 1] += a[b];
		a[b] = 0;
	}
	int mid = (ll + rr) >> 1;
	int ans = find(x, ll, mid, b + b);
	if (ans != mid) return ans;
	return max(mid, find(x, mid + 1, rr, b + b + 1));
}
int main()
{
	int n;
	while (cin >> n)
	{
		int m = 0;
		for (int i = 1; i <= n; i++)
		{
			cin >> b[i];
			m = max(m, b[i]);
		}
		for (int i = 1; i <= m; i++)
			add(i, D, 0, D, 1);
		for (int i = 1; i <= n; i++)
			if (b[i]) add(0, find(b[i] - 1, 0, D, 1), 0, D, 1);
		for (int i = 0; i <= m - 1; i++)
			cout << get(i, i, 0, D, 1) << ' ';
		cout << get(m, m, 0, D, 1) << endl;
		reset(m, 0, D, 1);
	}
	return 0;
}