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.
Stop thinking about the whole deck every turn. Focus on one question: what is the minimum cost needed before the win-condition becomes playable?
If the win-condition is at position , then every move before playing it must choose a card before it, and each such move shifts it forward by exactly .
So from position , you need exactly non-target moves before it reaches the first positions. Those moves must be on distinct cards that were originally before it.
Therefore, the cheapest way to make it playable from position costs the sum of the cheapest cards among the cards before it. Greedy “play the cheapest available card” actually achieves this.
Let be the sum of the cheapest cards before the win-condition, or if . Let be the sum of the cheapest non-win-condition cards. First play costs ; every later play costs .
The deck operation looks like it wants simulation pain. It doesn’t. The only important thing is the position of the win-condition.
Suppose the win-condition is currently at position . Since only the first cards are playable, every playable card is before the win-condition. Playing one of them moves it to the back, so the win-condition shifts forward by exactly .
That means we need exactly
ordinary card plays before the win-condition becomes playable.
Also, before the win-condition is played, a card before it cannot be played twice: once played, it goes behind the win-condition. So those cards are distinct cards chosen from the cards before it.
Therefore, the cost before the next win-condition play is at least the sum of the cheapest costs among those cards.
Mark the cheapest cards before the win-condition. There are exactly
unmarked cards before it.
While the win-condition is still not playable, the first positions are all before it. Since there are only unmarked cards total, at least one marked card must appear in the first positions. So if we always play the cheapest playable non-win-condition card, we can always play one of the marked cards.
After such moves, we have played exactly those cheapest marked cards. Greedy hits the lower bound, which means it is optimal. Nice. The queue tried to be scary and failed.
For the first win-condition play, it starts at position .
Let be the cost needed before the first play:
Then the first win-condition play itself costs , so the first successful play costs
After the win-condition is played, it is moved to the bottom, position . Now all other cards are before it. To make it playable again, we need ordinary plays.
Let be
So every additional win-condition play costs
If
we cannot even play the win-condition once, so the answer is .
Otherwise, after the first play we have energy left, and each extra play costs . Thus the answer is
We just sort two small lists of costs:
per test case, with memory. Since , this is hilariously safe.
Source note: I cross-checked the greedy proof against the official Codeforces Round 1086 editorial and rewrote the explanation here.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
ll sumSmallest(vector<int> v, int cnt) {
sort(v.begin(), v.end());
ll res = 0;
for (int i = 0; i < cnt; i++) res += v[i];
return res;
}
int main() {
setIO();
int T;
cin >> T;
while (T--) {
int n, k, p;
ll m;
cin >> n >> k >> p >> m;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
vector<int> before;
for (int i = 1; i < p; i++) before.push_back(a[i]);
vector<int> other;
for (int i = 1; i <= n; i++) {
if (i != p) other.push_back(a[i]);
}
ll A = sumSmallest(before, max(0, p - k));
ll B = sumSmallest(other, n - k);
ll first = A + a[p];
if (first > m) {
cout << 0 << '\n';
} else {
cout << 1 + (m - first) / (B + a[p]) << '\n';
}
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
ll sumSmallest(vector<int> v, int cnt) {
sort(v.begin(), v.end());
ll res = 0;
for (int i = 0; i < cnt; i++) res += v[i];
return res;
}
int main() {
setIO();
int T;
cin >> T;
while (T--) {
int n, k, p;
ll m;
cin >> n >> k >> p >> m;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
vector<int> before;
for (int i = 1; i < p; i++) before.push_back(a[i]);
vector<int> other;
for (int i = 1; i <= n; i++) {
if (i != p) other.push_back(a[i]);
}
ll A = sumSmallest(before, max(0, p - k));
ll B = sumSmallest(other, n - k);
ll first = A + a[p];
if (first > m) {
cout << 0 << '\n';
} else {
cout << 1 + (m - first) / (B + a[p]) << '\n';
}
}
}