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.
Think of every purchase as a multiset of powers of . A deal with parameter contributes one coin-type item worth watermelons.
The cheapest way per watermelon is the smallest deal. Deal has average cost , so bigger deals are only useful when the deal limit forces you to bundle watermelons.
The fewest possible deals is the sum of digits of in base . That is just the normal ternary representation: any time you replace one deal by three deals, the deal count increases by .
Start from the ternary representation. It uses the minimum number of deals but is expensive. To reduce cost while staying within , repeatedly split large deals into three smaller deals. Each split increases the deal count by .
A split of one deal into three deals always decreases the cost by exactly . So greedily split the largest available deals first until you cannot spend two more deals.
We need buy exactly watermelons using deals whose sizes are
A deal of size costs
For , that is just coins.
The annoying part is the limit: at most deals. The key is to stop thinking about “choosing deals” from scratch and instead start from the most compressed representation of .
Minimum possible number of deals
Write in base :
where each .
This means we can buy exactly watermelons using deals of size . The total number of deals is
This is actually the minimum possible number of deals. Why? Because three deals of size can always be compressed into one deal of size , reducing the deal count. The normal ternary representation is what you get after all possible compression is done.
So if
then the answer is . No magic trick exists; the seller has successfully scammed time itself.
Why splitting helps
The ternary representation uses the fewest deals, but not necessarily the minimum cost under the limit.
Smaller deals are cheaper per watermelon:
So, if we are allowed to use more deals, we want to split large deals into smaller ones.
Splitting one deal of size into three deals of size preserves the number of watermelons:
The deal count increases by .
Now compute how much money this saves.
Original cost:
New cost:
= 3^{x+1} + (x-1)3^{x-1}.$$ Savings: $$\left(3^{x+1} + x3^{x-1}\right) - \left(3^{x+1} + (x-1)3^{x-1}\right) = 3^{x-1}.$$ So splitting a larger deal saves more. A split at level $x$ saves $3^{x-1}$, which is bigger than every split at a smaller level. That gives the greedy rule: **Always split the largest available deal first, as long as we still have room for two extra deals.** **Algorithm** For each test case: 1. Convert $n$ to ternary digits $cnt[i]$. 2. Let $deals = \sum cnt[i]$. 3. If $deals > k$, print $-1$. 4. Compute the cost of this ternary representation. 5. From large powers down to $1$, split as many deals as possible: - splitting one deal at level $i$ needs $2$ extra deals; - it decreases cost by $3^{i-1}$; - it creates $3$ deals at level $i-1$. 6. Print the final cost. One subtle point: if $k - deals$ is odd, that last extra deal is useless. Every split increases the deal count by exactly $2$, so reachable deal counts have the same parity. Since the condition is “at most $k$”, we simply use the largest reachable count not exceeding $k$. **Complexity** Since $n \le 10^9$, there are only about $20$ ternary digits. Each test case is $O(\log_3 n)$, which is tiny. Like, aggressively tiny.#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
vector<ll> pow3(25, 1);
for (int i = 1; i < 25; i++) pow3[i] = pow3[i - 1] * 3;
int t;
cin >> t;
while (t--) {
ll n, k;
cin >> n >> k;
vector<ll> cnt(25, 0);
ll x = n, deals = 0, cost = 0;
for (int i = 0; x > 0; i++) {
cnt[i] = x % 3;
deals += cnt[i];
if (i == 0) cost += cnt[i] * 3;
else cost += cnt[i] * (pow3[i + 1] + i * pow3[i - 1]);
x /= 3;
}
if (deals > k) {
cout << -1 << '\n';
continue;
}
ll extra = k - deals;
for (int i = 24; i >= 1 && extra >= 2; i--) {
ll take = min(cnt[i], extra / 2);
if (take == 0) continue;
cost -= take * pow3[i - 1];
cnt[i] -= take;
cnt[i - 1] += take * 3;
extra -= take * 2;
}
cout << cost << '\n';
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
vector<ll> pow3(25, 1);
for (int i = 1; i < 25; i++) pow3[i] = pow3[i - 1] * 3;
int t;
cin >> t;
while (t--) {
ll n, k;
cin >> n >> k;
vector<ll> cnt(25, 0);
ll x = n, deals = 0, cost = 0;
for (int i = 0; x > 0; i++) {
cnt[i] = x % 3;
deals += cnt[i];
if (i == 0) cost += cnt[i] * 3;
else cost += cnt[i] * (pow3[i + 1] + i * pow3[i - 1]);
x /= 3;
}
if (deals > k) {
cout << -1 << '\n';
continue;
}
ll extra = k - deals;
for (int i = 24; i >= 1 && extra >= 2; i--) {
ll take = min(cnt[i], extra / 2);
if (take == 0) continue;
cost -= take * pow3[i - 1];
cnt[i] -= take;
cnt[i - 1] += take * 3;
extra -= take * 2;
}
cout << cost << '\n';
}
}