# Count pairs up to N having sum equal to their XOR

• Last Updated : 05 Oct, 2021

Given an integer N, the task is to count the number of pairs (X, Y) such that X + Y = X ^ Y and X + Y ≤ N
Note: ^ denotes Bitwise xor.

Examples:

Input: N = 3
Output: 9
Explanation: The pairs satisfying the given conditions are {{0, 0}, {0, 1}, {1, 0}, {0, 2}, {2, 0}, {3, 0}, {0, 3}, {2, 1}, {1, 2}}

Input: N = 10
Output: 37

Naive Approach: The simplest approach is to generate all possible pairs (X, Y) and check if the conditions X + Y = X ^ Y and X + Y ≤ N are satisfied or not.

Time Complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized based on the observation that X+Y ≥ X ^ Y for any value of X and Y. Consider the binary representation of X and Y. Let bit(X, pos) and bit(Y, pos) be the bits corresponding to X and Y at some fixed position pos. The condition X+Y = X^Y will be only satisfied if {bit(X, pos), bit(Y, pos)} ∈ {{1, 0}, {0, 1}, {0, 0}}. In other words, both X and Y cannot have set bits at the same positions.

In the efficient approach, the problem can be solved using Dynamic Programming. The problems have overlapping subproblems and optimal substructure. The subproblems are stored in a dp[][] table using memoization where dp[i][bound] stores the answer from the ‘i’th position to the end and bound is a boolean variable to ensure that the sum of numbers does not exceed N.

• Convert the limit N into its binary representation. Store the binary representation in a string, say S, so that iterating only over the length of the string and not the actual limit will be sufficient.
• Define a recursive function IsSumEqualsXor(i, bound) by performing the following steps.
• Check the base cases, if i == length of S then return 1, as a valid pair has been formed.
• If the result of the state dp[i][bound] has already been computed, then return the state dp[i][bound].
• At the current position i, any of the three pairs among {{0, 0}, {0, 1}, {1, 0}} can be assigned by checking few conditions. They are
• If the bound is true and the current character in S i.e S[i] is ‘0’ then, only {0, 0} can be placed as a valid pair in the current position. That is done to ensure that the sum does not exceed N.
• Otherwise, any pair among {{0, 0}, {0, 1}, {1, 0}} can be placed and bound is set to true or false accordingly.
• After placing a valid pair in the current position, recursively call the IsSumEqualsXor function for the element at index (i + 1).
• Return the sum of all possible valid placements of digits as the answer.

Below is the implementation of the above approach :

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;` `// 2D array for memoization``int` `dp;` `// Recursive Function to count pairs``// (x, y) such that x+y = x^y``int` `IsSumEqualsXor(``int` `i, ``int` `n,``                   ``bool` `bound, string& s)``{``    ``// If the string is traversed completely``    ``if` `(i == n)``        ``return` `1;` `    ``// If the current subproblem``    ``// is already calculated``    ``if` `(dp[i][bound] != -1)``        ``return` `dp[i][bound];` `    ``int` `ans = 0;` `    ``// If bound = 1 and  s[i] == '0',``    ``// only (0, 0) can be placed``    ``if` `(bound and s[i] == ``'0'``) {``        ``ans = IsSumEqualsXor(i + 1, n, 1, s);``    ``}` `    ``// Otherwise``    ``else` `{``        ``// Placing (0, 1) and (1, 0) are``        ``// equivalent. Hence, multiply by 2.``        ``ans = 2``              ``* IsSumEqualsXor(i + 1, n,``                               ``bound & (s[i] == ``'1'``), s);` `        ``// Place (0, 0) at the current position.``        ``ans += IsSumEqualsXor(i + 1, n, 0, s);``    ``}` `    ``// Return the answer``    ``return` `dp[i][bound] = ans;``}` `// Utility Function to convert N``// to its binary representation``string convertToBinary(``int` `n)``{``    ``string ans;``    ``while` `(n) {` `        ``char` `rem = ``char``(n % 2 + ``'0'``);``        ``ans.push_back(rem);``        ``n /= 2;``    ``}``    ``reverse(ans.begin(), ans.end());``    ``return` `ans;``}` `// Function to count pairs (x, y)``// such that x + y = x^y``void` `IsSumEqualsXorUtil(``int` `N)``{``    ``// Convert the number to``    ``// equivalent binary representation``    ``string s = convertToBinary(N);` `    ``// Initialize dp array with -1.``    ``memset``(dp, -1, ``sizeof` `dp);` `    ``// Print answer returned by recursive function``    ``cout << IsSumEqualsXor(0, s.size(), 1, s) << endl;``}` `// Driver code``int` `main()``{``    ``// Input``    ``int` `N = 10;` `    ``// Function call``    ``IsSumEqualsXorUtil(N);``    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;` `class` `GFG{` `// 2D array for memoization``static` `int` `[][]dp = ``new` `int``[``1000``][``2``];` `// Recursive Function to count pairs``// (x, y) such that x+y = x^y``static` `int` `IsSumEqualsXor(``int` `i, ``int` `n,``                   ``int` `bound, ``char``[] s)``{``    ``// If the String is traversed completely``    ``if` `(i == n)``        ``return` `1``;` `    ``// If the current subproblem``    ``// is already calculated``    ``if` `(dp[i][bound] != -``1``)``        ``return` `dp[i][bound];` `    ``int` `ans = ``0``;` `    ``// If bound = 1 and  s[i] == '0',``    ``// only (0, 0) can be placed``    ``if` `(bound!=``0` `&& s[i] == ``'0'``) {``        ``ans = IsSumEqualsXor(i + ``1``, n, ``1``, s);``    ``}` `    ``// Otherwise``    ``else` `{``        ``// Placing (0, 1) and (1, 0) are``        ``// equivalent. Hence, multiply by 2.``        ``ans = ``2``              ``* IsSumEqualsXor(i + ``1``, n,``                               ``bound!=``0` `& (s[i] == ``'1'``)?``1``:``0``, s);` `        ``// Place (0, 0) at the current position.``        ``ans += IsSumEqualsXor(i + ``1``, n, ``0``, s);``    ``}` `    ``// Return the answer``    ``return` `dp[i][bound] = ans;``}``static` `String reverse(String input) {``    ``char``[] a = input.toCharArray();``    ``int` `l, r = a.length - ``1``;``    ``for` `(l = ``0``; l < r; l++, r--) {``        ``char` `temp = a[l];``        ``a[l] = a[r];``        ``a[r] = temp;``    ``}``    ``return` `String.valueOf(a);``}``// Utility Function to convert N``// to its binary representation``static` `String convertToBinary(``int` `n)``{``    ``String ans=``""``;``    ``while` `(n>``0``) {` `        ``char` `rem = (``char``)(n % ``2` `+ ``'0'``);``        ``ans+=(rem);``        ``n /= ``2``;``    ``}``    ``ans = reverse(ans);``    ``return` `ans;``}` `// Function to count pairs (x, y)``// such that x + y = x^y``static` `void` `IsSumEqualsXorUtil(``int` `N)``{``    ``// Convert the number to``    ``// equivalent binary representation``    ``String s = convertToBinary(N);` `    ``// Initialize dp array with -1.``    ``for``(``int` `i = ``0``; i < dp.length; i++)``    ``{``        ``for` `(``int` `j = ``0``; j < dp[``0``].length; j++) {``            ``dp[i][j] = -``1``;``        ``}``    ``}` `    ``// Print answer returned by recursive function``    ``System.out.print(IsSumEqualsXor(``0``, s.length(), ``1``, s.toCharArray()) +``"\n"``);``}` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``// Input``    ``int` `N = ``10``;` `    ``// Function call``    ``IsSumEqualsXorUtil(N);``}``}` `// This code is contributed by shikhasingrajput`

## Python3

 `# Python3 program for the above approach` `# 2D array for memoization``dp ``=` `[[``-``1` `for` `i ``in` `range``(``2``)]``          ``for` `j ``in` `range``(``1000``)]` `# Recursive Function to count pairs``# (x, y) such that x+y = x^y``def` `IsSumEqualsXor(i, n, bound, s):``    ` `    ``# If the string is traversed completely``    ``if` `(i ``=``=` `n):``        ``return` `1` `    ``# If the current subproblem``    ``# is already calculated``    ``if` `(dp[i][bound] !``=` `-``1``):``        ``return` `dp[i][bound]` `    ``ans ``=` `0` `    ``# If bound = 1 and  s[i] == '0',``    ``# only (0, 0) can be placed``    ``if` `(bound ``and` `s[i] ``=``=` `'0'``):``        ``ans ``=` `IsSumEqualsXor(i ``+` `1``, n, ``1``, s)` `    ``# Otherwise``    ``else``:``        ` `        ``# Placing (0, 1) and (1, 0) are``        ``# equivalent. Hence, multiply by 2.``        ``ans ``=` `2` `*` `IsSumEqualsXor(``            ``i ``+` `1``, n, bound & (s[i] ``=``=` `'1'``), s)` `        ``# Place (0, 0) at the current position.``        ``ans ``+``=` `IsSumEqualsXor(i ``+` `1``, n, ``0``, s)``        ` `    ``dp[i][bound] ``=` `ans` `    ``# Return the answer``    ``return` `ans` `# Utility Function to convert N``# to its binary representation``def` `convertToBinary(n):``    ` `    ``ans ``=` `[]``    ` `    ``while` `(n):``        ``rem ``=` `chr``(n ``%` `2` `+` `48``)``        ``ans.append(rem)``        ``n ``/``/``=` `2``        ` `    ``ans ``=` `ans[::``-``1``]``    ``return` `ans` `# Function to count pairs (x, y)``# such that x + y = x^y``def` `IsSumEqualsXorUtil(N):``    ` `    ``# Convert the number to``    ``# equivalent binary representation``    ``s ``=` `convertToBinary(N)` `    ``# Print answer returned by recursive function``    ``print``(IsSumEqualsXor(``0``, ``len``(s), ``1``, s))` `# Driver code``if` `__name__ ``=``=` `'__main__'``:``    ` `    ``# Input``    ``N ``=` `10``    ` `    ``# Function call``    ``IsSumEqualsXorUtil(N)``    ` `# This code is contributed by ipg2016107`

## C#

 `// C# program for the above approach``using` `System;` `class` `GFG{` `// 2D array for memoization``static` `int` `[,]dp = ``new` `int``[1000, 2];` `// Recursive Function to count pairs``// (x, y) such that x+y = x^y``static` `int` `IsSumEqualsXor(``int` `i, ``int` `n,``                          ``int` `bound, ``char``[] s)``{``    ` `    ``// If the String is traversed completely``    ``if` `(i == n)``        ``return` `1;` `    ``// If the current subproblem``    ``// is already calculated``    ``if` `(dp[i,bound] != -1)``        ``return` `dp[i,bound];` `    ``int` `ans = 0;` `    ``// If bound = 1 and  s[i] == '0',``    ``// only (0, 0) can be placed``    ``if` `(bound != 0 && s[i] == ``'0'``)``    ``{``        ``ans = IsSumEqualsXor(i + 1, n, 1, s);``    ``}` `    ``// Otherwise``    ``else``    ``{``        ` `        ``// Placing (0, 1) and (1, 0) are``        ``// equivalent. Hence, multiply by 2.``        ``ans = 2 * IsSumEqualsXor(i + 1, n,``                                 ``bound != 0 &``                                 ``(s[i] == ``'1'``) ? 1 : 0, s);` `        ``// Place (0, 0) at the current position.``        ``ans += IsSumEqualsXor(i + 1, n, 0, s);``    ``}` `    ``// Return the answer``    ``return` `dp[i, bound] = ans;``}` `static` `String reverse(String input)``{``    ``char``[] a = input.ToCharArray();``    ``int` `l, r = a.Length - 1;``    ` `    ``for``(l = 0; l < r; l++, r--)``    ``{``        ``char` `temp = a[l];``        ``a[l] = a[r];``        ``a[r] = temp;``    ``}``    ``return` `String.Join(``""``, a);``}` `// Utility Function to convert N``// to its binary representation``static` `String convertToBinary(``int` `n)``{``    ``String ans = ``""``;``    ``while` `(n > 0)``    ``{``        ``char` `rem = (``char``)(n % 2 + ``'0'``);``        ``ans += (rem);``        ``n /= 2;``    ``}``    ``ans = reverse(ans);``    ``return` `ans;``}` `// Function to count pairs (x, y)``// such that x + y = x^y``static` `void` `IsSumEqualsXorUtil(``int` `N)``{``    ` `    ``// Convert the number to``    ``// equivalent binary representation``    ``String s = convertToBinary(N);` `    ``// Initialize dp array with -1.``    ``for``(``int` `i = 0; i < dp.GetLength(0); i++)``    ``{``        ``for``(``int` `j = 0; j < dp.GetLength(1); j++)``        ``{``            ``dp[i, j] = -1;``        ``}``    ``}` `    ``// Print answer returned by recursive function``    ``Console.Write(IsSumEqualsXor(0, s.Length, 1,``                                 ``s.ToCharArray()) +``"\n"``);``}` `// Driver code``public` `static` `void` `Main(String[] args)``{``    ` `    ``// Input``    ``int` `N = 10;` `    ``// Function call``    ``IsSumEqualsXorUtil(N);``}``}` `// This code is contributed by umadevi9616`

## Javascript

 ``

Output:

`37`

Time Complexity: O(Log2N)
Auxiliary Space: O(Log2N)

My Personal Notes arrow_drop_up