abc376E Max x Sum

chenfy27的刷题记录 / 2024-10-29 / 原文

有序列A[N]和B[N],选出一组大小为K的下标,让A[i]的最大值乘以(B[i]之和)的结果最小,求最小值。
1<=T<=2E5, 1<=K<=N<=2E5, 1<=A[i],B[i]<=1E6

分析:因为A[i]跟B[i]要同步选,因此对下标排序,然后枚举每个A[i]作为最大值,从B[i]中选出最小的K个求和,得到结果,B[i]之和可以用堆来维护。

#include <bits/stdc++.h>
using i64 = long long;

void solve() {
	int N, K;
	std::cin >> N >> K;
	std::vector<int> A(N), B(N);
	for (int i = 0; i < N; i++) {
		std::cin >> A[i];
	}
	for (int i = 0; i < N; i++) {
		std::cin >> B[i];
	}

	std::vector<int> ord(N);
	std::iota(ord.begin(), ord.end(), 0);
	std::sort(ord.begin(), ord.end(),
		[&](int i, int j) {
			return A[i] < A[j];
		});

	i64 ans = 1E18;
	i64 sum = 0;
	std::priority_queue<int> pq;
	for (auto i : ord) {
		sum += B[i];
		pq.push(B[i]);
		while (pq.size() > K) {
			sum -= pq.top();
			pq.pop();
		}
		if (pq.size() == K) {
			ans = std::min(ans, A[i] * sum);
		}
	}
	std::cout << ans << "\n";
}

int main() {
	std::cin.tie(0)->sync_with_stdio(0);
	int t = 1;
	std::cin >> t;
	while (t--) solve();
	return 0;
}