Use a Trie to store binary representations of numbers (most significant bit first).
For each number, traverse the Trie trying to take the opposite bit at each level (to maximize XOR). If the opposite bit doesn't exist, take the same bit.
Build the Trie while querying: for each new number, first query the max XOR with existing numbers, then insert the number.