- 252's solution
-
P252's Solution
- @ 2026-4-7 20:36:00
考虑扫描序列时动态维护函数 ,注意到 ,容易用线段树维护。
#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;
}