Table of Contents

ExplanationImplementation

Official Editorial (C++)

Explanation

A good strategy to tackle these problems is just to simulate and try to spot a pattern. Also, keep in mind what matters in each step and construct cases around it. Finally, process queries in a way so that you can differentiate between all of the cases.

Here, we can query from the most significant to the least significant bit. This is because in bitwise, since higher bits always take priority, it is hard to bypass the effects of the higher bits if you don't already know them.

First, we can submit a query (c,d)=(0,0)(c, d) = (0, 0) to figure out whether aa or bb is greater (this will become helpful later on). Now, loop from most to least significant bits. Let curA\mathtt{curA} and curB\mathtt{curB} be the values for the bits of aa and bb we already know. We can try to differentiate the two numbers at this bit. We can submit two queries, in the form (curA2B,curB)(\mathtt{curA}| 2^B, \mathtt{curB}), and (curA,curB2B)(\mathtt{curA}, \mathtt{curB} | 2^B) where we are currently looping on bit BB. We also know that there are the following four cases we have to consider:

  1. Both aa and bb has bit BB activated
  2. Neither aa and bb has bit BB activated
  3. Only aa has bit BB activated
  4. Only bb has bit BB activated

When it is the first two cases, the results for the two queries will be different. This is because the since we are using XOR on an activated bit in one number and not the other, there will always be one query greater, since they have the same bit at this position. If the first query yields 1-1 or second query yields a 11, both aa and bb must have bit BB activated.

Thus for the last two cases, the results for the two queries will be different. To differentiate which number will take the bit, remember we know which number is greater so far! In this case, the greater number must take this bit, or else the smaller number must take it and that leads to a contradiction since higher bits take priority. Now, we have to update which is greater based on our current query to remove the effect of the more significant bits.

Implementation

Time Complexity: O(1)\mathcal{O}(1)

C++

#include <bits/stdc++.h>
using namespace std;
int ask(int a, int b) {
cout << "? " << a << " " << b << endl;
int res;
cin >> res;
return res;
}

Java

import java.io.*;
import java.util.*;
public class EhabAndXOR {
public static void main(String[] args) {
Kattio io = new Kattio();
boolean aGreaterThanB = (ask(0, 0) == 1 ? true : false);
int a = 0;
int b = 0;

Python

def ask(a: int, b: int):
print(f"? {a} {b}")
res = int(input())
return res
a_greater_than_b = ask(0, 0) == 1
a, b = 0, 0
# 2^29 is the maximum bit due to constraints

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!