Till I Collapse CodeForces - 786C
题面
题解
首相想当\(k\)固定怎么算, 很简单想出数据结构维护\(nlogn\)的做法,
关键当\(k\) 从 \(1\) 到 \(n\),怎么办
在仔细看看\(k\)固定时的复杂度,应该是\(ans \times logn\),其中ans为答案
那从\(1\) 到 \(n\) 的 \(\sum ans\)最坏情况是\(nlogn\)
所以当\(k\) 从 \(1\) 到 \(n\) 的复杂度不是\(n^2logn\) 而是 \(nlog^2n\)
int n, c[N];
void add(int x, int val) {for (; x <= n; x += -x & x) c[x] += val; }
int ask(int w) {
int p = 0;
for (int i = 16; ~i; --i)
if (p + (1 << i) <= n && c[p + (1 << i)] <= w) {
p |= 1 << i;
w -= c[p];
}
return p + 1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n;
vector<int> nxt(n + 1, n + 1), ls(n + 1), ans(n + 1);
vector<stack<int>> need(n + 1);
for (int i = 1; i <= n; ++i) {
int x; cin >> x;
if (ls[x]) nxt[ls[x]] = i;
else add(i, 1);
ls[x] = i;
need[1].emplace(i);
}
for (int i = 1; i <= n; ++i) {
for (int j = 0; !need[i].empty(); ++j) {
int cur = ask(need[i].top());
++ans[need[i].top()];
if (cur < n + 1)
need[cur].emplace(need[i].top());
need[i].pop();
}
add(i, -1);
add(nxt[i], 1);
}
for (int i = 1; i <= n; ++i) cout << ans[i] << ' ';
return 0;
}