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.
Forget about the exact chosen at first. After spending coins, you only care about the final upper bounds : is there some whose XOR is ?
For each bit , count how many current upper bounds have bit set. Compare these counts from high to low with the bits of , lexicographically. The counts are not taken mod 2. That is the bait.
At the first bit where the count is greater than the bit of , you are already done: that extra high-bit freedom can absorb any lower XOR. If the count is equal, that bit is forced, so strip it away and continue lower.
When has a at bit but no current number has bit , you must create exactly one such bit. If the current residues are all below , raising the largest residue to costs , which is obviously best.
Per query, you only need the largest original numbers. If the scan has not stopped yet, every higher bit appeared in at most one relevant number, so at most about 30 large blockers can hide the best current residue. Keeping the top 40 is plenty.
Think of the operation like this: for one query, we choose final upper bounds and pay . Then we only need to know whether some with can XOR to .
The sneaky part is that feasibility is not about XORing the themselves. It is about the ranges . Big difference. Parity-only thinking gets cooked here.
The feasibility test
For every bit , define
the number of values whose bit is set.
Compare the sequence with the binary digits of , also from high to low. The target is achievable iff this count sequence is lexicographically at least the bit sequence of .
Since each bit of is only or , the only real failure is: at the first differing bit, has but the count is .
Why does this work? Look at the highest bit still being considered.
If more numbers have bit than , then we have slack and all lower bits become free. If , one number with bit set can simply choose any lower value below , so the high bit stays and the lower XOR can be anything. If and at least two numbers have bit , choose one as exactly and another as any lower value. Again, lower bits are whatever we want.
If the count equals , the bit is forced. If both are , no one can use this bit, so we just continue below it. If both are , exactly one number has this bit, and it must provide the high bit of the XOR. Its remaining lower freedom is just its lower part, so we clear bit from that upper bound and continue.
If the count is less than , then and nobody can provide that bit. Impossible.
That gives a clean high-to-low check.
Now minimize coins
We simulate that same check, but when it would fail, we pay the cheapest amount to fix it.
Maintain current residual upper bounds after all forced higher bits have been stripped. Process bits from down to .
Let have be the number of residuals with bit set, and need be bit of .
If have > need, stop. The current paid amount already works.
If have == need, this bit is forced, so clear bit from every residual and continue.
If have < need, then need=1 and have=0. Every residual is below , so we must raise one of them until bit becomes . Raising residual to exactly costs , so we choose the largest . After that, this bit is forced and the chosen number has lower residual .
Raising above is not magic. Any extra amount only buys lower residual bits, and the later steps can pay for those exactly if they are actually useful. So setting it to exactly is enough.
Why top 40 values are enough
Doing this over all values for every query would be way too slow.
Sort descending and keep only the largest 40 values. This is safe because there are only 30 bits.
Suppose the scan reaches bit . Then for every higher bit, we did not stop, meaning the count at that bit was equal to the corresponding bit of . So each higher bit can account for at most one relevant large number. Across all higher bits, that is at most 30 annoying blockers.
Therefore, if bit has two available numbers, at least two of them appear among roughly the first 32 original values. If bit has none and we need the largest residual below , that largest residual is also behind at most those 30 blockers. Keeping 40 is just a comfortable no-drama margin.
So each query costs only tiny operations.
Complexity
Sorting costs per test case. Each query costs , which is effectively constant. With the given limits, this is very comfortably AC.
#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;
constexpr int KEEP = 40;
while (T--) {
int n, q;
cin >> n >> q;
vector<int> a(n);
for (int &x : a) cin >> x;
sort(a.begin(), a.end(), greater<int>());
int m = min(n, KEEP);
vector<int> top(a.begin(), a.begin() + m);
while (q--) {
int c;
cin >> c;
vector<int> b = top;
ll ans = 0;
for (int bit = 29; bit >= 0; --bit) {
int need = (c >> bit) & 1;
int have = 0;
for (int x : b) have += (x >> bit) & 1;
if (have > need) break;
if (have < need) {
int id = 0;
for (int i = 1; i < m; ++i) {
if (b[i] > b[id]) id = i;
}
ans += (1LL << bit) - b[id];
b[id] = 0;
} else {
for (int &x : b) x &= ~(1 << bit);
}
}
cout << ans << '\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();
int T;
cin >> T;
constexpr int KEEP = 40;
while (T--) {
int n, q;
cin >> n >> q;
vector<int> a(n);
for (int &x : a) cin >> x;
sort(a.begin(), a.end(), greater<int>());
int m = min(n, KEEP);
vector<int> top(a.begin(), a.begin() + m);
while (q--) {
int c;
cin >> c;
vector<int> b = top;
ll ans = 0;
for (int bit = 29; bit >= 0; --bit) {
int need = (c >> bit) & 1;
int have = 0;
for (int x : b) have += (x >> bit) & 1;
if (have > need) break;
if (have < need) {
int id = 0;
for (int i = 1; i < m; ++i) {
if (b[i] > b[id]) id = i;
}
ans += (1LL << bit) - b[id];
b[id] = 0;
} else {
for (int &x : b) x &= ~(1 << bit);
}
}
cout << ans << '\n';
}
}
}