P9113 [IOI2009] Hiring
P9113 [IOI2009] Hiring
考虑选择一些工人后怎么分配工资。根据监管局的要求,所有人的工资
将所有工人按
因此,问题转化为:每次插入一个数
输出方案也是容易的。记录
时间复杂度
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
bool Mbe;
constexpr int N = 5e5 + 5;
ll W;
int n, b[N], buc[N];
struct worker {
int s, q, id;
bool operator < (const worker &z) const {
return s * z.q > q * z.s;
}
} w[N];
ll c[N];
int d[N];
void add(int x, int v) {
while(x <= n) c[x] += v, d[x]++, x += x & -x;
}
pair<ll, int> query(ll lim) {
ll sc = 0, sd = 0, p = 0;
for(int i = 18; ~i; i--) {
int np = p + (1 << i);
if(np > n) continue;
if(sc + c[np] > lim) continue;
sc += c[p = np], sd += d[p];
}
return make_pair(sc, sd);
}
bool Med;
int main() {
fprintf(stderr, "%.3lf MB\n", (&Mbe - &Med) / 1048576.0);
#ifdef ALEX_WEI
FILE* IN = freopen("1.in", "r", stdin);
FILE* OUT = freopen("1.out", "w", stdout);
#endif
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> W;
for(int i = 1; i <= n; i++) {
cin >> w[i].s >> w[i].q, buc[w[i].q]++, w[i].id = i;
}
sort(w + 1, w + n + 1);
for(int i = 1; i < N; i++) buc[i] += buc[i - 1];
int pos = 0, ans = -1;
ll nu, de;
for(int i = n; i; i--) {
int p = buc[w[i].q]--;
add(p, w[i].q);
auto t = query(W * w[i].q / w[i].s);
ll sq = t.first, cnt = t.second;
ll nu1 = w[i].s * sq, de1 = w[i].q;
if(cnt > ans || cnt == ans && nu1 * de < nu * de1) {
ans = cnt, pos = i, nu = nu1, de = de1;
}
}
sort(w + pos, w + n + 1, [&](auto x, auto y) {
return x.q < y.q;
});
cout << ans << "\n";
for(int i = 0; i < ans; i++) cout << w[pos + i].id << "\n";
cerr << 1e3 * clock() / CLOCKS_PER_SEC << " ms\n";
return 0;
}