这是 P4447 [AHOI2018初中组] 分组 的代码:
#include <iostream>
#include <stdio.h>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
const int S = 1e5 + 5;
int n, a[S], n2;
vector<int> b;
int ans = S;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", a + i);
}
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; i++) {
if (b.empty() || b.back() != a[i]) {
b.push_back(a[i]);
}
}
n2 = b.size();
vector<int> c;
int j = 1, cnt[S];
for (int i = 0; i < n2; i++) {
while (c.empty() || b[i] == c.back() + 1) {
c.push_back(b[i]);
i++;
}
int delta = a[j];
int left = 0;
for (auto p : c) {
while (a[j] == p && j <= n) {
cnt[a[j] - delta]++;
j++;
left++;
}
}
int res = n, fst = 0;
while (left > 0) {
int l = 0;
int idx = fst;
while (true) {
left--;
l++;
if (cnt[idx + 1] < cnt[idx]) {
cnt[idx]--;
break;
}
cnt[idx]--;
idx++;
}
res = min(res, l);
while (cnt[fst] == 0) {
fst++;
}
if (fst >= c.size()) {
break;
}
}
ans = min(ans, res);
for (int k = 0; k <= c.size(); k++) {
cnt[k] = 0;
}
c.clear();
i--;
// cout << res << endl << endl;
}
cout << ans;
return 0;
}
/*
6
-1 -1 2 2 3 5
*/
虽然写的有点复杂但感觉 for (int i = 0; i < n2; i++) 这个循环的均摊复杂度是 O(n) 的,把 sort 算上时间复杂度应该是正确的 O(nlogn) 啊,但是最后的 hack 过不掉
Record: https://www.luogu.com.cn/record/138234647
感觉是 for (int i = 0; i < n2; i++) 这个循环的复杂度搞错了,求大佬们帮本蒟蒻看看 Orz
可能会十点多再回复不好意思 UwU