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.
Because is only being reordered, and are fixed. Use So the problem is secretly: minimize .
If the current range is exactly , life is perfect: pair every with its bitwise complement inside those bits. Then for every position, so every OR is .
For a general prefix , let be the smallest all-ones mask with . Any number in the top part has its complement also inside .
Pair all numbers in that top part with their complements: set . These pairs all have AND , and they consume exactly the interval plus its complement interval in the right way. What's left is just a smaller prefix.
After pairing with mask , the only unassigned positions are So recurse on . This gives the permutation directly. The maximum sum can then be computed from the produced permutation, no fancy formula needed.
We need maximize where is a permutation of .
The important identity is:
So
The first two sums are fixed, because is only a reorder of . Therefore maximizing the OR sum is exactly the same as minimizing
So the real question is: can we pair numbers so that as many pairs as possible have bitwise AND equal to ?
The perfect case
If , then the set is exactly all -bit numbers:
Then pair every number with its -bit complement:
Example for :
For every pair, because their bits are exact opposites. That means every OR becomes , which is obviously as clean as it gets.
What if the prefix is incomplete?
Suppose is not all ones. Let be the smallest all-ones mask such that .
For example, if , then .
We would love to pair every with , because then . But some complements may be bigger than , which are not allowed. Classic annoying prefix problem.
A number has valid complement if
That is equivalent to
So every position can safely be paired with
These pairs have AND , so they are definitely optimal locally. No downside, no weird trick: if you can make a pair contribute zero to the thing we are minimizing, take it.
Now what remains unpaired?
The positions below :
And the unused values are exactly the same prefix. So the problem repeats on a smaller :
That gives a very simple recursive construction:
This eventually bottoms out when nothing is left.
Why this is optimal
Look at the highest bit of the current mask . The current range is with .
The numbers in the upper half have that highest bit set. To make their AND contribution avoid that expensive bit, they should be paired with numbers whose highest bit is not set. Pairing with does even better: it avoids every shared bit, not just the highest one.
The interval is exactly the part where this complement is available inside the current prefix. Those elements can be made zero-cost, and zero is the absolute minimum possible contribution. After removing them, the leftover instance is again a smaller prefix, so recursion handles the rest optimally.
Basically: whenever the complement exists, use it. The remaining hole is still the same problem, just smaller. Bitmasks being nice for once. Wild.
Computing the answer
The construction gives the permutation. Then just compute
with long long.
The easy version has total , so this is easily fast enough. The recursion removes at least one highest-bit block each time, so the total work over a test case is .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
void build(int r, vector<int>& a) {
if (r < 0) return;
int m = 1;
while (m <= r) m <<= 1;
--m;
int start = m - r;
for (int x = start; x <= r; ++x) {
a[x] = m - x;
}
build(start - 1, a);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int l, r;
cin >> l >> r;
vector<int> a(r + 1, -1);
build(r, a);
ll ans = 0;
for (int i = 0; i <= r; ++i) {
ans += (a[i] | i);
}
cout << ans << '\n';
for (int i = 0; i <= r; ++i) {
cout << a[i] << " \n"[i == r];
}
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
void build(int r, vector<int>& a) {
if (r < 0) return;
int m = 1;
while (m <= r) m <<= 1;
--m;
int start = m - r;
for (int x = start; x <= r; ++x) {
a[x] = m - x;
}
build(start - 1, a);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int l, r;
cin >> l >> r;
vector<int> a(r + 1, -1);
build(r, a);
ll ans = 0;
for (int i = 0; i <= r; ++i) {
ans += (a[i] | i);
}
cout << ans << '\n';
for (int i = 0; i <= r; ++i) {
cout << a[i] << " \n"[i == r];
}
}
return 0;
}