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.
Each valid is just a submask of . Try thinking bit-by-bit instead of trying to construct the actual array.
For a fixed length , for every set bit of , let be how many array elements contain bit . Then , and the sum becomes .
The reverse is also true: if you find such counts , you can build an array by putting bit into the first elements. So the whole problem is minimizing the maximum count used by any allowed bit.
For a candidate answer , check whether can be paid using at most coins of each allowed denomination . Since denominations are powers of two, scan from high bits to low bits greedily.
Maintain the unpaid prefix demand in units of the current bit. At bit , double the previous demand, add the -th bit of , and if has bit , subtract up to . This feasibility check is monotone, so binary search .
Research used: the official Codeforces problem page and the official Educational Codeforces Round 187 editorial/accepted solution at https://codeforces.com/blog/entry/151612. The statement here is still the canonical source.
The key is to stop trying to guess the array directly. That path gets messy fast, and the mess is fake.
Each valid number is a submask of . For a fixed length , look at one bit position where has a set bit. Across the whole array, this bit can appear in some number of elements. Since there are only elements,
The contribution of that bit to the total sum is , so the problem for a fixed becomes:
This is not just necessary, it is sufficient. If such counts exist, build the array by putting bit into the first elements. Every element still uses only bits from , and the total contribution of bit is exactly .
So the answer is the minimum possible value of over all representations of using the allowed powers of two. Nice and clean. Annoyingly clean, even.
Now we need a feasibility check for a candidate .
Think of every allowed bit of as a coin denomination , and you have at most coins of each allowed denomination. Can you form exactly ?
Because all denominations are powers of two, greedily handling bigger denominations first is optimal. Scan bits from high to low and maintain need: the remaining unpaid prefix of , measured in units of the current power of two.
Before processing bit , suppose need is the unpaid amount from higher bits measured in units of . Moving to bit doubles it, and then we add the actual bit of :
Now need is how many units of must still be covered by denominations or smaller.
If bit is set in , we may use up to coins of value , so we do:
If bit is not set in , we cannot pay anything at this level, so all demand must be pushed down to smaller bits.
After processing bit , there are no smaller positive denominations left. Therefore the candidate is feasible iff need == 0.
Why is the greedy step valid? At bit , using a coin of value only reduces demand. It does not consume any smaller coins, and any unpaid unit would need to be replaced by smaller denominations later. So there is never a reason to save an available larger coin for later. This gives an induction: after every processed bit, greedy leaves the minimum possible unpaid demand among all choices using the processed denominations.
Feasibility is monotone: if length works, then any larger length also works, because every bit gets a larger count limit. So we binary search the minimum .
Before binary searching, check whether a solution exists at all. Since , using is always enough if any representation exists: if the smallest allowed denomination divides , we could use that denomination repeatedly. The same feasibility check with limit catches all possible/impossible cases.
Edge cases:
long long is fine for input, and using __int128 inside the check makes overflow a non-issue.Complexity per test case is
because binary search takes about steps and each feasibility check scans about bits. With test cases, this is easily inside the limit.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
bool can(ll s, ll m, ll lim) {
__int128 need = 0;
for (int bit = 60; bit >= 0; --bit) {
need = need * 2 + ((s >> bit) & 1LL);
if ((m >> bit) & 1LL) {
if (need <= lim) need = 0;
else need -= lim;
}
}
return need == 0;
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
ll s, m;
cin >> s >> m;
if (!can(s, m, s)) {
cout << -1 << '\n';
continue;
}
ll lo = 1, hi = s;
while (lo < hi) {
ll mid = lo + (hi - lo) / 2;
if (can(s, m, mid)) hi = mid;
else lo = mid + 1;
}
cout << 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);
}
bool can(ll s, ll m, ll lim) {
__int128 need = 0;
for (int bit = 60; bit >= 0; --bit) {
need = need * 2 + ((s >> bit) & 1LL);
if ((m >> bit) & 1LL) {
if (need <= lim) need = 0;
else need -= lim;
}
}
return need == 0;
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
ll s, m;
cin >> s >> m;
if (!can(s, m, s)) {
cout << -1 << '\n';
continue;
}
ll lo = 1, hi = s;
while (lo < hi) {
ll mid = lo + (hi - lo) / 2;
if (can(s, m, mid)) hi = mid;
else lo = mid + 1;
}
cout << lo << '\n';
}
return 0;
}