Problem: 2057C - Trip to the Olympiad
Language: C++20 (GCC 13-64)

Previous submission (verdict: Wrong answer on test 1):
#include <bits/stdc++.h>
using namespace std;
 
typedef long long ll;
 
// We define -infinity (for impossible states)
const ll MINF = -1e18;
 
// Global arrays to store the bit–representation of l and r.
// For pos = 30 down to 0.
int Lbits[32], Rbits[32];
 
// We will use a 4-dimensional DP state:
//   dp[pos][lbMask][ubMask][diffMask]
// where:
//   - pos: current bit position we are processing (from 30 down to 0).
//   - lbMask: a 3–bit mask (bits 0–2) for the three numbers; for a given number i, 
//             bit i = 1 means that in some higher bit the number already exceeded l.
//   - ubMask: similarly, bit i = 1 means the number is already below r.
//   - diffMask: a 3–bit mask representing which pairs of numbers have already been made different:
//             bit0: numbers 0 and 1 differ; bit1: numbers 0 and 2 differ; bit2: numbers 1 and 2 differ.
 
// Our dp value is the maximum additional sum (from the current pos downwards) that can be obtained
// from a valid assignment (or MINF if no valid assignment exists).
 
int dp[33][8][8][8];
bool vis[33][8][8][8];
 
// For reconstruction we store our decision in each state.
struct Choice {
    int nb0, nb1, nb2;  // chosen bits at this pos for numbers 0,1,2
    int nlmask, nubmask, ndmask; // new masks after this bit
    bool used;
};
 
Choice choiceRec[33][8][8][8];
 
// The recursive DP function.
// pos: current bit (from 30 down to 0); when pos < 0 we are done.
// lbMask, ubMask, diffMask: as explained above.
int rec (int pos, int lbMask, int ubMask, int diffMask) {
    if(pos < 0){
        // At the end, we require that all three pairs are different.
        if(diffMask == 7) return 0;
        else return MINF;
    }
    if(vis[pos][lbMask][ubMask][diffMask]) return dp[pos][lbMask][ubMask][diffMask];
    vis[pos][lbMask][ubMask][diffMask] = true;
    int best = MINF;
    Choice bestChoice;
    bestChoice.used = false;
    // There are 8 possible assignments for the three bits at this position.
    for(int mask = 0; mask < 8; mask++){
        // Extract bits for numbers 0,1,2.
        int b0 = (mask >> 0) & 1;
        int b1 = (mask >> 1) & 1;
        int b2 = (mask >> 2) & 1;
 
        bool valid = true;
        // Check for each number if our choice is allowed by the bounds.
        for(int i = 0; i < 3; i++){
            int chosen = (mask >> i) & 1;
            int lbBit = Lbits[pos];
            int rbBit = Rbits[pos];
            // If we haven’t yet exceeded l for number i, then we must choose a bit >= Lbits[pos].
            if( ((lbMask >> i) & 1) == 0 ){
                if(chosen < lbBit) { valid = false; break; }
            }
            // Similarly, if we haven’t yet gone below r for number i, then chosen bit must be <= Rbits[pos].
            if( ((ubMask >> i) & 1) == 0 ){
                if(chosen > rbBit) { valid = false; break; }
            }
        }
        if(!valid) continue;
 
        // Update the lower-bound and upper-bound flags for each number.
        int newLB = 0, newUB = 0;
        for(int i = 0; i < 3; i++){
            int chosen = (mask >> i) & 1;
            int lbBit = Lbits[pos], rbBit = Rbits[pos];
            // For lower-bound: if already above l then remain; otherwise, if chosen > Lbits[pos] then we are now above.
            if((lbMask >> i) & 1) newLB |= (1 << i);
            else {
                if(chosen > lbBit) newLB |= (1 << i);
            }
            // For upper-bound: similarly.
            if((ubMask >> i) & 1) newUB |= (1 << i);
            else {
                if(chosen < rbBit) newUB |= (1 << i);
            }
        }
 
        // Update the diff flags: for each pair, if the bits chosen differ then mark that pair as “different.”
        int newDiff = diffMask;
        if(b0 != b1) newDiff |= 1;       // pair (0,1)
        if(b0 != b2) newDiff |= 2;       // pair (0,2)
        if(b1 != b2) newDiff |= 4;       // pair (1,2)
 
        // The contribution at this bit is 2*(1<<pos) if not all three bits are equal.
        int contrib = 0;
        if(!( (b0==b1) && (b1==b2) ))
            contrib = 2 * (1 << pos);
 
        int nxt = rec(pos-1, newLB, newUB, newDiff);
        if(nxt == MINF) continue;
        int total = contrib + nxt;
        if(total > best){
            best = total;
            bestChoice.nb0 = b0;
            bestChoice.nb1 = b1;
            bestChoice.nb2 = b2;
            bestChoice.nlmask = newLB;
            bestChoice.nubmask = newUB;
            bestChoice.ndmask = newDiff;
            bestChoice.used = true;
        }
    }
    dp[pos][lbMask][ubMask][diffMask] = best;
    choiceRec[pos][lbMask][ubMask][diffMask] = bestChoice;
    return best;
}
 
// Reconstruct the three numbers from the DP decisions.
void reconstruct(int pos, int lbMask, int ubMask, int diffMask, ll &a, ll &b, ll &c) {
    if(pos < 0) return;
    Choice ch = choiceRec[pos][lbMask][ubMask][diffMask];
    // Append the chosen bits (we are processing from MSB to LSB).
    a = (a << 1) | ch.nb0;
    b = (b << 1) | ch.nb1;
    c = (c << 1) | ch.nb2;
    reconstruct(pos-1, ch.nlmask, ch.nubmask, ch.ndmask, a, b, c);
}
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
 
    int t; 
    cin >> t;
    while(t--){
        unsigned int L, R;
        cin >> L >> R;
        // It is given that r-l > 1 so there are at least 3 numbers.
 
        // Fill in the bit arrays for positions 30 down to 0.
        for (int pos = 30; pos >= 0; pos--){
            Lbits[pos] = (L >> pos) & 1;
            Rbits[pos] = (R >> pos) & 1;
        }
 
        // Clear the memo arrays.
        memset(vis, 0, sizeof(vis));
 
        int best = rec(30, 0, 0, 0);
        // (We do not really need the best sum; we only need a triple achieving it.)
 
        ll a = 0, b = 0, c = 0;
        reconstruct(30, 0, 0, 0, a, b, c);
 
        // Output the triple.
        cout << a << " " << b << " " << c << "\n";
    }
    return 0;
}


Submission (verdict: Accepted):
#include <bits/stdc++.h>
using namespace std;
 
typedef long long ll;
 
// A sufficiently small negative value used as -infinity.
const ll MINF = -1000000000000000000LL; // -1e18

// Global arrays to store the bits of L and R, for positions 30 down to 0.
int Lbits[32], Rbits[32];
 
// DP memo arrays. We use 33 (for pos 0..30, plus one extra for pos=-1) x 8 x 8 x 8 states.
ll dp[33][8][8][8];
bool vis[33][8][8][8];
 
// For reconstruction, we store our decision for each state.
struct Choice {
    int nb0, nb1, nb2;     // Chosen bits for numbers 0,1,2 at the current position.
    int nlmask, nubmask, ndmask; // New masks after this bit.
    bool used;
};
 
Choice choiceRec[33][8][8][8];
 
// DP function: pos is the current bit position (from 30 down to 0). 
// lbMask and ubMask are 3–bit masks for the three numbers indicating whether that number is
// already above L or below R, respectively. diffMask is a 3–bit mask for pairs: bit0 for (0,1),
// bit1 for (0,2), and bit2 for (1,2) indicating that the pair has already differed in some higher bit.
ll rec (int pos, int lbMask, int ubMask, int diffMask) {
    if(pos < 0){
        // At the end, ensure that all three pairs differ (i.e. diffMask==7).
        return (diffMask == 7 ? 0LL : MINF);
    }
    if(vis[pos][lbMask][ubMask][diffMask])
        return dp[pos][lbMask][ubMask][diffMask];
    vis[pos][lbMask][ubMask][diffMask] = true;
    ll best = MINF;
    Choice bestChoice;
    bestChoice.used = false;
    
    // Try all 8 possible assignments for the three numbers' current bit.
    for(int mask = 0; mask < 8; mask++){
        int b0 = (mask >> 0) & 1;
        int b1 = (mask >> 1) & 1;
        int b2 = (mask >> 2) & 1;
        
        bool valid = true;
        // Check each number i (0,1,2) against the lower and upper bound for this bit.
        for (int i = 0; i < 3; i++){
            int chosen = (mask >> i) & 1;
            int lbBit = Lbits[pos];
            int rbBit = Rbits[pos];
            // If number i has not yet been confirmed to be above L, then its chosen bit must be >= Lbits[pos].
            if(((lbMask >> i) & 1) == 0 && chosen < lbBit) { valid = false; break; }
            // Similarly, if number i is not yet confirmed to be below R, then its chosen bit must be <= Rbits[pos].
            if(((ubMask >> i) & 1) == 0 && chosen > rbBit) { valid = false; break; }
        }
        if(!valid) continue;
 
        // Update lower-bound and upper-bound flags for each number.
        int newLB = 0, newUB = 0;
        for(int i = 0; i < 3; i++){
            int chosen = (mask >> i) & 1;
            int lbBit = Lbits[pos], rbBit = Rbits[pos];
            // For lower-bound: if we were already above L, remain; else if chosen > Lbits[pos], we become free.
            if(((lbMask >> i) & 1) == 1 || chosen > lbBit)
                newLB |= (1 << i);
            // For upper-bound: if we were already below R, remain; else if chosen < Rbits[pos], we become free.
            if(((ubMask >> i) & 1) == 1 || chosen < rbBit)
                newUB |= (1 << i);
        }
 
        // Update the diff mask for pairs. If the chosen bits differ for a pair, mark that pair.
        int newDiff = diffMask;
        if(b0 != b1) newDiff |= 1;   // pair (0,1)
        if(b0 != b2) newDiff |= 2;   // pair (0,2)
        if(b1 != b2) newDiff |= 4;   // pair (1,2)
 
        // Compute the contribution at this bit: if not all three bits are equal, add 2 * (1 << pos).
        ll contrib = 0;
        if(!(b0 == b1 && b1 == b2))
            contrib = 2LL * (1LL << pos);
 
        ll nxt = rec(pos-1, newLB, newUB, newDiff);
        if(nxt == MINF) continue;
        ll total = contrib + nxt;
        if(total > best){
            best = total;
            bestChoice.nb0 = b0;
            bestChoice.nb1 = b1;
            bestChoice.nb2 = b2;
            bestChoice.nlmask = newLB;
            bestChoice.nubmask = newUB;
            bestChoice.ndmask = newDiff;
            bestChoice.used = true;
        }
    }
    dp[pos][lbMask][ubMask][diffMask] = best;
    choiceRec[pos][lbMask][ubMask][diffMask] = bestChoice;
    return best;
}
 
// Reconstruct the three numbers from the stored DP choices.
void reconstruct(int pos, int lbMask, int ubMask, int diffMask, ll &a, ll &b, ll &c) {
    if(pos < 0) return;
    Choice ch = choiceRec[pos][lbMask][ubMask][diffMask];
    a = (a << 1) | ch.nb0;
    b = (b << 1) | ch.nb1;
    c = (c << 1) | ch.nb2;
    reconstruct(pos-1, ch.nlmask, ch.nubmask, ch.ndmask, a, b, c);
}
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
 
    int t;
    cin >> t;
    while(t--){
        unsigned int L, R;
        cin >> L >> R;
        // According to the problem, r - l > 1, so there are at least 3 numbers.
 
        // Fill the bit representations of L and R for bit positions 30 down to 0.
        for (int pos = 30; pos >= 0; pos--){
            Lbits[pos] = (L >> pos) & 1;
            Rbits[pos] = (R >> pos) & 1;
        }
 
        // Clear the DP memo arrays.
        memset(vis, 0, sizeof(vis));
 
        ll best = rec(30, 0, 0, 0);
        // (We don't actually need the best sum; any triple achieving it is accepted.)
 
        ll a = 0, b = 0, c = 0;
        reconstruct(30, 0, 0, 0, a, b, c);
 
        cout << a << " " << b << " " << c << "\n";
    }
    return 0;
}