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.
First ignore the “equals exactly” part. If the target is , every final value must contain every 1 bit of . For each , ask: what is the smallest number [3mnot below[0m a_iX$?
For one number, if it is missing some required bits of , only the highest missing required bit matters. You set that bit, keep higher bits unchanged, and set lower bits as cheaply as possible: equal to the lower bits of .
The base cost for “AND is a superset of ” can be summed by grouping numbers by their highest missing bit. A superset-count SOS DP over masks gives counts like “how many contain this mask?”
After the base move, let the temporary values be . If their AND is already , stop. Otherwise let be the highest unwanted bit that is still common to all . Any fix must make some element carry past bit .
If that carry lands at bit , the lower bits should become exactly Xmod 2^t. This is valid only if bit is not destroyed as the only zero among the ’s, so among temporary values at least two must have bit . Minimize the extra cost by maximizing the selected value’s lower bits.
Let . All initial values and all queries are below .
We will solve every query independently, but we need preprocessing good enough for queries. The trick is to stop thinking about individual increments one by one. Carries are the whole game here.
Step 1: force the 1 bits of
For a fixed , every final value must contain all bits of . For each , define
The cost is unavoidable in any valid solution, because every valid final value for this element must contain . So first compute the base cost
How do we compute this fast?
For one number , suppose the highest bit of that is missing in is . Then all required bits above are already fine. The cheapest fix is:
So the increment is
Now group all numbers whose highest missing required bit is . If is the mask of required bits of above , then this group is exactly:
Precompute
with SOS DP over supersets. Then the group size is
We also need the sum of over that group. Instead of storing 20 big sum arrays, decompose it by bits:
That count is
That gives in about time. Tiny.
Step 2: exact AND, not just superset
After replacing every by , all values contain . Let
If , the base cost is already the answer.
Otherwise there is at least one unwanted common bit. Let be the highest bit such that has and has . This bit is common to every , so some element must be increased until bit becomes .
Here is the important carry fact: to turn bit from to by increasing a number, you must carry into some bit where that number currently has ; or into bit .
When we carry into bit , the cheapest possible new lower part is exactly . So for a selected temporary value with bit , the extra cost is
This clears all unwanted common bits below , including bit . Bits above do not change.
But there is one annoying gotcha, because of course there is. If and the selected element was the only temporary value with bit , then after setting its bit to , bit becomes common to all values. That would make the AND too large. So a carry into is valid only when at least two temporary values have bit .
Carrying into bit is always allowed: all other temporary values are still below , so bit is not common.
So the extra cost is the minimum over valid :
Step 3: count zeros of temporary values
For a bit with , when does have bit ?
Exactly when:
If misses a required higher bit, the fix carries above and resets bit to .
Let be the mask of bits of strictly above . Then
so
The highest unwanted common bit is the highest with .
Step 4: maximize the lower part among zero-bit candidates
For a valid carry bit , we need
There are two ways happens:
where next means the smallest number not below the first argument that contains the second mask.
next is monotone, so for case 2 we only need the maximum lower part among numbers with:
Precompute this with another SOS DP, this time taking maximums over high masks for each bit .
That is the whole thing. The implementation looks scary only because the masks are doing accounting for us; the idea is just “base force , then one carry fixes the highest extra bit.” Carries are rude, but at least they are predictable rude.
Complexity
Preprocessing is .
Each query costs about in the worst case, with small constants.
Memory is .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
const int B = 20;
const int U = 1 << B;
int n, q;
cin >> n >> q;
vector<int> a(n);
vector<int> cnt(U, 0);
int maxA = 0;
for (int &x : a) {
cin >> x;
cnt[x]++;
maxA = max(maxA, x);
}
for (int b = 0; b < B; b++) {
for (int mask = 0; mask < U; mask++) {
if ((mask & (1 << b)) == 0) {
cnt[mask] += cnt[mask | (1 << b)];
}
}
}
vector<int> off(B);
int total = 0;
for (int t = 0; t < B; t++) {
off[t] = total;
total += 1 << (B - t - 1);
}
vector<int> bestLow(total, -1);
for (int x : a) {
for (int t = 0; t < B; t++) {
if (((x >> t) & 1) == 0) {
int high = x >> (t + 1);
int low = x & ((1 << t) - 1);
int id = off[t] + high;
bestLow[id] = max(bestLow[id], low);
}
}
}
for (int t = 0; t < B; t++) {
int d = B - t - 1;
int sz = 1 << d;
int o = off[t];
for (int b = 0; b < d; b++) {
for (int mask = 0; mask < sz; mask++) {
if ((mask & (1 << b)) == 0) {
bestLow[o + mask] = max(bestLow[o + mask], bestLow[o + (mask | (1 << b))]);
}
}
}
}
auto nextWith = [&](int start, int need, int bits) {
for (int k = bits - 1; k >= 0; k--) {
if ((need & (1 << k)) && ((start & (1 << k)) == 0)) {
int lowMask = (1 << k) - 1;
int clearLow = ~((1 << (k + 1)) - 1);
return (start & clearLow) | (1 << k) | (need & lowMask);
}
}
return start;
};
auto solve = [&](int X) -> ll {
ll base = 0;
int H = 0;
for (int k = B - 1; k >= 0; k--) {
int bit = 1 << k;
if ((X & bit) == 0) continue;
int c0 = cnt[H] - cnt[H | bit];
ll sumLow = 0;
for (int r = 0; r < k; r++) {
int rb = 1 << r;
sumLow += 1LL * rb * (cnt[H | rb] - cnt[H | bit | rb]);
}
int xlow = X & (bit - 1);
base += 1LL * c0 * (bit + xlow) - sumLow;
H |= bit;
}
int g = -1;
H = 0;
for (int t = B - 1; t >= 0; t--) {
int bit = 1 << t;
if (X & bit) {
H |= bit;
} else {
int ones = cnt[H | bit];
if (ones == n) {
g = t;
break;
}
}
}
if (g == -1) return base;
int maxM = nextWith(maxA, X, B);
ll extra = 1LL * U + X - maxM;
for (int t = g + 1; t < B; t++) {
int bit = 1 << t;
if (X & bit) continue;
int belowEq = (1 << (t + 1)) - 1;
int Ht = X & ~belowEq;
int zeros = n - cnt[Ht | bit];
if (zeros < 2) continue;
int xlow = X & (bit - 1);
int best = -1;
if (cnt[Ht] < n) best = xlow;
int highNeed = Ht >> (t + 1);
int low = bestLow[off[t] + highNeed];
if (low != -1) {
best = max(best, nextWith(low, xlow, t));
}
if (best != -1) {
extra = min(extra, 1LL * bit + xlow - best);
}
}
return base + extra;
};
while (q--) {
int X;
cin >> X;
cout << solve(X) << '\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();
const int B = 20;
const int U = 1 << B;
int n, q;
cin >> n >> q;
vector<int> a(n);
vector<int> cnt(U, 0);
int maxA = 0;
for (int &x : a) {
cin >> x;
cnt[x]++;
maxA = max(maxA, x);
}
for (int b = 0; b < B; b++) {
for (int mask = 0; mask < U; mask++) {
if ((mask & (1 << b)) == 0) {
cnt[mask] += cnt[mask | (1 << b)];
}
}
}
vector<int> off(B);
int total = 0;
for (int t = 0; t < B; t++) {
off[t] = total;
total += 1 << (B - t - 1);
}
vector<int> bestLow(total, -1);
for (int x : a) {
for (int t = 0; t < B; t++) {
if (((x >> t) & 1) == 0) {
int high = x >> (t + 1);
int low = x & ((1 << t) - 1);
int id = off[t] + high;
bestLow[id] = max(bestLow[id], low);
}
}
}
for (int t = 0; t < B; t++) {
int d = B - t - 1;
int sz = 1 << d;
int o = off[t];
for (int b = 0; b < d; b++) {
for (int mask = 0; mask < sz; mask++) {
if ((mask & (1 << b)) == 0) {
bestLow[o + mask] = max(bestLow[o + mask], bestLow[o + (mask | (1 << b))]);
}
}
}
}
auto nextWith = [&](int start, int need, int bits) {
for (int k = bits - 1; k >= 0; k--) {
if ((need & (1 << k)) && ((start & (1 << k)) == 0)) {
int lowMask = (1 << k) - 1;
int clearLow = ~((1 << (k + 1)) - 1);
return (start & clearLow) | (1 << k) | (need & lowMask);
}
}
return start;
};
auto solve = [&](int X) -> ll {
ll base = 0;
int H = 0;
for (int k = B - 1; k >= 0; k--) {
int bit = 1 << k;
if ((X & bit) == 0) continue;
int c0 = cnt[H] - cnt[H | bit];
ll sumLow = 0;
for (int r = 0; r < k; r++) {
int rb = 1 << r;
sumLow += 1LL * rb * (cnt[H | rb] - cnt[H | bit | rb]);
}
int xlow = X & (bit - 1);
base += 1LL * c0 * (bit + xlow) - sumLow;
H |= bit;
}
int g = -1;
H = 0;
for (int t = B - 1; t >= 0; t--) {
int bit = 1 << t;
if (X & bit) {
H |= bit;
} else {
int ones = cnt[H | bit];
if (ones == n) {
g = t;
break;
}
}
}
if (g == -1) return base;
int maxM = nextWith(maxA, X, B);
ll extra = 1LL * U + X - maxM;
for (int t = g + 1; t < B; t++) {
int bit = 1 << t;
if (X & bit) continue;
int belowEq = (1 << (t + 1)) - 1;
int Ht = X & ~belowEq;
int zeros = n - cnt[Ht | bit];
if (zeros < 2) continue;
int xlow = X & (bit - 1);
int best = -1;
if (cnt[Ht] < n) best = xlow;
int highNeed = Ht >> (t + 1);
int low = bestLow[off[t] + highNeed];
if (low != -1) {
best = max(best, nextWith(low, xlow, t));
}
if (best != -1) {
extra = min(extra, 1LL * bit + xlow - best);
}
}
return base + extra;
};
while (q--) {
int X;
cin >> X;
cout << solve(X) << '\n';
}
return 0;
}