Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
After sorting both people’s cards in decreasing order, the best way to take exactly cards from Vadim is always “take his top ”. Same for Kostya. So every query is really choosing only one number: how many cards come from Vadim.
For a query , if Vadim contributes cards, then Kostya contributes . The valid interval is
The value is .
The function is unimodal/concave. When you increase by , you swap in Vadim’s next card and remove Kostya’s current last chosen card, so
Those differences only go downward as increases.
Since the differences are monotonic, you do not need to scan the whole valid interval. Binary search for the first where , then check that point and its neighbors/interval ends. That is where the peak stops climbing.
Even simpler: if the unconstrained peak wants too few or too many Vadim cards, clamp it into the valid interval. Binary search inside using the condition meaning “moving right still improves the answer.” Then evaluate the final .
We have two piles of cards, and each query asks:
The important thing: the query limits only care about counts, not which exact positions. So if we decide to take cards from Vadim, obviously we take his best cards. Taking worse cards while leaving better cards unused would be self-sabotage, and we are not doing that today.
Sort both arrays in decreasing order and build prefix sums:
with .
Now each query becomes a one-dimensional optimization.
Valid range for Vadim's count
Suppose Vadim takes cards. Then Kostya takes cards.
Vadim's limit gives:
Kostya's limit gives:
Also counts cannot be negative or exceed :
So the valid interval is:
The statement guarantees , so this interval is non-empty.
For a fixed valid , the best sum is:
So we need:
A brute force scan is too slow because the interval can be huge and there are many queries.
Why has one peak
Look at what happens when we increase by .
We take one more card from Vadim: the next card is .
We take one fewer card from Kostya: the removed card is , because previously Kostya took cards.
So:
Since both arrays are sorted decreasing:
Therefore:
is non-increasing as increases.
That means climbs for a while, then stops, then falls. It is a discrete concave/unimodal function. The max is exactly around the place where the slope changes from positive to non-positive.
Binary search the peak
Inside the valid interval , we can binary search for the largest such that moving from to is still profitable.
Moving right improves the answer when:
Using the difference formula:
This condition is monotonic: once it becomes false, it stays false.
So we binary search on in :
A clean way:
Start with lo = L, hi = R.
While lo < hi:
mid = (lo + hi) / 2a[mid + 1] > b[z - mid], set lo = mid + 1hi = midAt the end, lo is a maximizing count for Vadim. Then the answer is:
Index details
Use 1-indexed sorted arrays for the cards:
Prefix sums are 0-indexed by count:
The comparison uses:
This is valid because mid < R <= z, so z - mid >= 1. Also mid + 1 <= R <= x <= n, so the a index is valid.
Correctness proof
For any query, if exactly cards are chosen from Vadim, the best such choice is the top cards of array , and the best cards from Kostya are the top cards of array . Therefore the best value for this fixed is .
The only valid values of are those satisfying all count constraints, which gives:
So the query answer is the maximum of over .
Now consider the difference:
Because is sorted decreasing, is non-increasing as grows. Because is sorted decreasing, is non-decreasing as grows. Hence the whole difference is non-increasing.
So is unimodal: it increases while the difference is positive and does not increase after the difference becomes non-positive. The binary search finds the first valid position where moving right is no longer profitable, or the right endpoint if it stays profitable throughout. That position maximizes on .
Therefore the algorithm returns the maximum possible sum for every query.
Complexity
Sorting costs:
Each query costs:
Memory is:
This easily fits the limits. No heroic data structure nonsense needed; just sort, prefix sums, and a binary search that actually knows what it is searching for.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n, m, q;
cin >> n >> m >> q;
vector<ll> a(n + 1), b(m + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= m; i++) cin >> b[i];
sort(a.begin() + 1, a.end(), greater<ll>());
sort(b.begin() + 1, b.end(), greater<ll>());
vector<ll> pa(n + 1), pb(m + 1);
for (int i = 1; i <= n; i++) pa[i] = pa[i - 1] + a[i];
for (int i = 1; i <= m; i++) pb[i] = pb[i - 1] + b[i];
while (q--) {
int x, y, z;
cin >> x >> y >> z;
int lo = max(0, z - y);
int hi = min(x, z);
while (lo < hi) {
int mid = (lo + hi) / 2;
if (a[mid + 1] > b[z - mid]) {
lo = mid + 1;
} else {
hi = mid;
}
}
cout << pa[lo] + pb[z - lo] << '\n';
}
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n, m, q;
cin >> n >> m >> q;
vector<ll> a(n + 1), b(m + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= m; i++) cin >> b[i];
sort(a.begin() + 1, a.end(), greater<ll>());
sort(b.begin() + 1, b.end(), greater<ll>());
vector<ll> pa(n + 1), pb(m + 1);
for (int i = 1; i <= n; i++) pa[i] = pa[i - 1] + a[i];
for (int i = 1; i <= m; i++) pb[i] = pb[i - 1] + b[i];
while (q--) {
int x, y, z;
cin >> x >> y >> z;
int lo = max(0, z - y);
int hi = min(x, z);
while (lo < hi) {
int mid = (lo + hi) / 2;
if (a[mid + 1] > b[z - mid]) {
lo = mid + 1;
} else {
hi = mid;
}
}
cout << pa[lo] + pb[z - lo] << '\n';
}
}
return 0;
}