D - コンテストの準備 / Contest Preparation 解説 by admin
Claude Opus 5 (High)Overview
The problem asks us to choose \(K\) problems out of \(N\) such that the sum of their scores is at least \(P\), while minimizing the maximum difficulty among them. This can be solved by “sorting by difficulty and maintaining the sum of the top \(K\) largest scores while incrementally adding candidates from the beginning.”
Analysis
Insight 1: Fix the Answer and Formulate a Decision Problem
For problems asking for the “minimum possible value of the maximum difficulty”, a standard approach is to fix the answer to \(X\) and convert it into a decision problem.
“Can we choose \(K\) problems such that the maximum difficulty is at most \(X\) and the total score is at least \(P\)?”
This decision is simple. The only usable problems are those satisfying \(B_i \le X\), so we just need to take the \(K\) problems with the largest scores \(A_i\) among them and check if their sum is at least \(P\) (since we want to maximize the sum, greedily taking the largest scores is optimal). Of course, if there are fewer than \(K\) problems satisfying \(B_i \le X\), it is impossible.
Insight 2: Monotonicity
Increasing \(X\) only increases the set of usable problems, so if it is achievable with \(X\), it is also achievable with any \(X' > X\). In other words, the decision result is monotonic with respect to \(X\), so binary search can be used.
However, the meaningful candidates for \(X\) are essentially just the values of \(B_i\). Thus, if we sort by \(B\) and consider “being able to use up to the first \(i\) problems” as we vary \(i\), we can solve this in a single scan without writing a binary search. This approach is easier to implement.
Issue with the Naive Approach
If, for each \(i\), we compute the “sum of the top \(K\) largest \(A\) among the first \(i\) problems” by sorting each time, it would take \(O(N K \log N)\) or \(O(N^2 \log N)\), which will exceed the time limit for \(N = 10^5\).
Instead, we can use the fact that the set of the top \(K\) elements barely changes as we increment \(i\) by \(1\). Whether a new element \(A_i\) enters this set can be determined simply by comparing it with the “minimum value among the \(K\) elements we currently hold”. This can be maintained precisely using a priority queue that allows extraction of the minimum element (min-heap).
Algorithm
- Pair each problem as \((B_i, A_i)\) and sort them in ascending order of \(B\).
- Prepare a min-heap
pq(the currently selected values of \(A\)) and their total sumsum. - Iterate through \(i = 0, 1, \dots, N-1\) in order:
- If the size of
pqis less than \(K\), add \(A_i\) and updatesum += A_i. - If the size is \(K\) and \(A_i > \) the minimum element of
pq, remove the minimum element and insert \(A_i\) (also updatingsum). This consistently maintains the “top \(K\) largest \(A\) among the first \(i+1\) elements”. - After that, if the size of
pqis \(K\) andsum\(\ge P\), the answer is \(B_i\) (the \(i\)-th \(B\) after sorting), so print it and terminate.
- If the size of
- If the condition is not met by the end, print \(-1\).
Why is \(B_i\) at the moment the condition is first satisfied the answer? The fact that the condition was not satisfied up to the \((i-1)\)-th problem means that no matter how we choose \(K\) problems from the first \(i\) problems (\(0\) to \(i-1\)), the sum of scores is strictly less than \(P\) (since the sum of the top \(K\) largest scores is the maximum possible sum). Therefore, an optimal solution must include the \(i\)-th problem, and the maximum difficulty among the chosen problems will be \(B_i\). Even if multiple problems share the same value of \(B\), the output value will be identical, so this is not an issue.
Concrete Example
Consider the case where \(N=4, K=2, P=10\), and \((A,B) = (3,5), (8,2), (4,9), (6,3)\).
Sorting in ascending order of \(B\) gives \((8,2), (6,3), (3,5), (4,9)\).
- \(i=0\): pq \(=\{8\}\), sum \(=8\) (size \(1 < K\))
- \(i=1\): pq \(=\{8,6\}\), sum \(=14 \ge 10\) and size \(=2=K\) \(\rightarrow\) answer \(B=3\)
Indeed, choosing the problems with scores \(8\) and \(6\) gives a total of \(14 \ge 10\), and the maximum difficulty is \(3\).
Complexity
- Time Complexity: \(O(N \log N)\) (sorting and heap operations each take \(O(N \log N)\))
- Space Complexity: \(O(N)\)
Key Implementation Points
Overflow: Since \(P \le 10^{14}\) and the sum of scores can be up to \(10^5 \times 10^9 = 10^{14}\), it will overflow a 32-bit
int. Use a 64-bit integer (long long) for the sum and \(P\).Sorting pairs: Storing elements in
pair<long long, long long>in the order of \((B, A)\) allowssortto order them by \(B\) in ascending order (be careful not to place \(A\) as the first element).How to write a min-heap: In C++,
priority_queueis a max-heap by default, so writepriority_queue<long long, vector<long long>, greater<long long>>to make it a min-heap.Do not check the condition with fewer than \(K\) elements: Since we need to choose exactly \(K\) problems, be sure to include the condition
pq.size() == K.If implemented using binary search, within the decision function we can find the “sum of the top \(K\) largest \(A\) among problems with \(B_i \le X\)” by sorting descending, which will pass in about \(O(N \log^2 N)\). However, the scanning approach described above is simpler.
Source Code
#include <bits/stdc++.h>
using namespace std;
int main(){
int N; long long K, P;
scanf("%d %lld %lld", &N, &K, &P);
vector<pair<long long,long long>> v(N); // (B, A)
for(int i=0;i<N;i++){
long long a,b;
scanf("%lld %lld",&a,&b);
v[i] = {b,a};
}
sort(v.begin(), v.end());
priority_queue<long long, vector<long long>, greater<long long>> pq;
long long sum = 0;
for(int i=0;i<N;i++){
long long a = v[i].second;
if((long long)pq.size() < K){
pq.push(a);
sum += a;
} else if(!pq.empty() && a > pq.top()){
sum -= pq.top();
pq.pop();
pq.push(a);
sum += a;
}
if((long long)pq.size() == K && sum >= P){
printf("%lld\n", v[i].first);
return 0;
}
}
printf("-1\n");
return 0;
}
This editorial was generated by claude5opus-high.