Program to count pairs with XOR in a range in Python

Suppose we have an array nums and two values l and r. We need to find the number of nice pairs, where a nice pair is (i, j) such that 0 and l .

For example, if nums = [4,1,7,2], l = 2, and r = 6, the output will be 6 because the nice pairs are:

  • (0,1): 4 XOR 1 = 5

  • (0,2): 4 XOR 7 = 3

  • (0,3): 4 XOR 2 = 6

  • (1,2): 1 XOR 7 = 6

  • (1,3): 1 XOR 2 = 3

  • (2,3): 7 XOR 2 = 5

Algorithm

The solution uses a helper function count_pairs_less_than(nums, x) that counts pairs with XOR less than x. Then we calculate pairs in range [l, r] using: count_pairs_less_than(r+1) - count_pairs_less_than(l).

The algorithm works by:

  • Using frequency counting to track element occurrences

  • Processing bits from least significant to most significant

  • For each bit position, counting valid pairs and updating frequencies

Implementation

from collections import Counter

def count_pairs_with_xor_in_range(nums, l, r):
    def count_pairs_less_than(nums, x):
        count = Counter(nums)
        result = 0
        
        while x:
            if x & 1:  # If current bit of x is 1
                # Count pairs where XOR has this bit as 0
                result += sum(count[a] * count[(x - 1) ^ a] for a in count)
            
            # Right shift all numbers by 1 bit and update frequencies
            new_count = Counter()
            for a in count:
                new_count[a >> 1] += count[a]
            count = new_count
            
            x >>= 1
        
        return result // 2  # Divide by 2 to avoid double counting
    
    return count_pairs_less_than(nums, r + 1) - count_pairs_less_than(nums, l)

# Example usage
nums = [4, 1, 7, 2]
l = 2
r = 6
result = count_pairs_with_xor_in_range(nums, l, r)
print(f"Number of nice pairs: {result}")

The output of the above code is ?

Number of nice pairs: 6

How It Works

The algorithm processes bits from right to left:

  1. Bit Processing: For each bit position, it checks if that bit is set in the target value

  2. Pair Counting: When a bit is set, it counts pairs that would have XOR less than the current target

  3. Frequency Update: Numbers are right-shifted and frequencies are recalculated for the next iteration

  4. Range Calculation: Uses the difference between counts to get pairs in the specified range

Step-by-Step Example

# Let's trace through a smaller example
nums = [1, 3, 4]
l, r = 2, 5

# Check all pairs manually
pairs = []
for i in range(len(nums)):
    for j in range(i + 1, len(nums)):
        xor_val = nums[i] ^ nums[j]
        if l <= xor_val <= r:
            pairs.append((i, j, nums[i], nums[j], xor_val))
            print(f"Pair ({i},{j}): {nums[i]} XOR {nums[j]} = {xor_val}")

print(f"Total nice pairs: {len(pairs)}")

The output of the above code is ?

Pair (0,1): 1 XOR 3 = 2
Pair (0,2): 1 XOR 4 = 5
Pair (1,2): 3 XOR 4 = 7
Total nice pairs: 2

Time and Space Complexity

  • Time Complexity: O(n × log(max_value)) where n is the array length

  • Space Complexity: O(n) for the frequency counter

Conclusion

This algorithm efficiently counts XOR pairs in a range using bit manipulation and frequency counting. The key insight is converting the range problem into counting pairs less than specific values, then taking their difference.

Updated on: 2026-03-26T14:48:35+05:30

540 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements