Count of distinct XORs formed by rearranging two Binary strings
Last Updated :
20 Mar, 2023
Given two binary strings A and B of equal length N, the task is to find the number of distinct XORs possible by arbitrarily reordering the two binary strings. Since the number can be large enough, find the number modulo 109 + 7
Examples:
Input: A = “00”, B = “01”
Output: 2
Explanation:
There are two possible results by rearranging the digits of the string B.
They are: “10” and “01”
Input: A = “010”, B = “100”
Output: 4
Explanation:
There are four possible results possible by rearranging the digits of both the strings.
They are: “000”, “110”, “011”, “101”
Approach:
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
Therefore, to get an XOR value as ‘1’ at any index of the result string, the input strings must have odd number of 1s at that index.
- Now, we will try to rearrange the Binary strings in a way, that maximum number of indices have an odd number of 1s at them. This can be visualized by the following example:
- Therefore, from the above observation, the idea is to find the minimum and the maximum number of 1’s possible by reordering the strings.
- To find the Maximum ‘1’s: The maximum ‘1’s in the result would occur when maximum {0, 1} and {1, 0} pairs are formed. Therefore,
Maximum number of {0, 1} pairs = minimum(count of ‘0’ in A, count of ‘1’ in B)
Maximum number of {1, 0} pairs = minimum(count of ‘1’ in A, count of ‘0’ in B)
Therefore, Maximum number of ‘1’s in the XOR = Maximum number of {0, 1} pairs + Maximum number of {1, 0} pairs
- To find the Minimum ‘1’s: This case can be seen as the converse of the maximum number of ‘0’s in the result. Similarly, the maximum ‘0’s in the result would occur when maximum {0, 0} and {1, 1} pairs are formed. Therefore,
Maximum number of {0, 0} pairs = minimum(count of ‘0’ in A, count of ‘0’ in B)
Maximum number of {1, 1} pairs = minimum(count of ‘1’ in A, count of ‘1’ in B)
Maximum number of ‘0’s in the XOR = Maximum number of {0, 0} pairs + Maximum number of {1, 1} pairs
Therefore, Minimum number of ‘1’s in the XOR = N – Maximum number of ‘0’s in the XOR
- All the combinations of 1’s can be formed in between these two numbers (minimum and maximum) with the difference of 2.
- Finally, the total number of possible ways to get the result can be calculated by the number of combinations from the minimum number of 1’s and the maximum number of 1’s with a step of 2.
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h>
using namespace std;
long long power( long long a, long long b, long long mod)
{
long long aa = 1;
while (b)
{
if (b&1)
{
aa = aa * a;
aa %= mod;
}
a = a * a;
a %= mod;
b /= 2;
}
return aa;
}
long long nCrRangeSum( long long n, long long r1,
long long r2, long long p)
{
long long num = 1, den = 1;
long long sum = 0;
if (r1 == 0)
sum += 1;
for ( int i = 0; i < r2; i++)
{
num = (num * (n - i)) % p;
den = (den * (i + 1)) % p;
if (i - r1 >= -1 and (i - r1 + 1) % 2 == 0)
{
sum += (num * power(den, p - 2, p)) % p;
sum %= p;
}
}
return sum;
}
int compute(string A, string B, int N)
{
int c0A = 0, c1A = 0, c0B = 0, c1B = 0;
for ( char c:A) {
if (c == '1' )
c1A += 1;
else if (c == '0' )
c0A += 1;
}
for ( char c:B){
if (c == '1' )
c1B += 1;
else if (c == '0' )
c0B += 1;
}
int max1xor = min(c0A, c1B) + min(c1A, c0B);
int min1xor = N - min(c0B, c0A) - min(c1A, c1B);
int ans = nCrRangeSum(N, min1xor, max1xor, 1000000000 + 7);
return ans;
}
int main()
{
long long N = 3;
string A = "010" ;
string B = "100" ;
cout << compute(A, B,N);
return 0;
}
|
Java
class GFG
{
static long mod_power( long a, long b,
long mod)
{
long result = 1l;
while (b > 0 )
{
if ((b& 1 ) == 0 )
{
result = a * a;
a %= mod;
b /= 2 ;
}
else
{
result = result * a;
result %= mod;
}
}
return result;
}
static long nCr_RangeSum( long n, long r1,
long r2, long p)
{
long num = 1 , den = 1 ;
long sum = 0l;
if (r1 == 0 )
sum += 1l;
for ( int i = 0 ; i < r2; i++)
{
num = (num * (n - i)) % p;
den = (den * (i + 1 )) % p;
if (i - r1 >= - 1 && (i - r1 + 1 ) % 2 == 0 )
{
sum += (num * mod_power(den, p - 2 , p)) % p;
sum %= p;
}
}
return sum;
}
static long compute(String A, String B, int N)
{
int c0A = 0 , c1A = 0 , c0B = 0 , c1B = 0 ;
for ( char c : A.toCharArray())
{
if (c == '1' )
c1A += 1 ;
else if (c == '0' )
c0A += 1 ;
}
for ( char c : B.toCharArray())
{
if (c == '1' )
c1B += 1 ;
else if (c == '0' )
c0B += 1 ;
}
int max1xor = Math.min(c0A, c1B) + Math.min(c1A, c0B);
int min1xor = N - Math.min(c0B, c0A) - Math.min(c1A, c1B);
long ans = nCr_RangeSum(N, min1xor, max1xor, 1000000000 + 7 );
return ans;
}
public static void main(String[] args)
{
int N = 3 ;
String A = "010" ;
String B = "100" ;
System.out.print(compute(A, B, N));
}
}
|
Python3
def nCrRangeSum(n, r1, r2, p):
num = den = 1
sum = 0
if r1 = = 0 :
sum + = 1
for i in range (r2):
num = (num * (n - i)) % p
den = (den * (i + 1 )) % p
if (i - r1 > = - 1 and (i - r1 + 1 ) % 2 = = 0 ):
sum + = (num * pow (den, p - 2 , p)) % p
sum % = p
return sum
def compute(A, B):
c0A = c1A = c0B = c1B = 0
for c in A:
if c = = '1' :
c1A + = 1
elif c = = '0' :
c0A + = 1
for c in B:
if c = = '1' :
c1B + = 1
elif c = = '0' :
c0B + = 1
max1xor = min (c0A, c1B) + min (c1A, c0B)
min1xor = N - min (c0B, c0A) - min (c1A, c1B)
ans = nCrRangeSum(N, min1xor, max1xor, 10 * * 9 + 7 )
return ans
if __name__ = = "__main__" :
N = 3
A = "010"
B = "100"
print (compute(A, B))
|
C#
using System;
class GFG{
static long mod_power( long a, long b,
long mod)
{
long result = 1;
while (b > 0)
{
if ((b & 1) == 0)
{
result = a * a;
a %= mod;
b /= 2;
}
else
{
result = result * a;
result %= mod;
}
}
return result;
}
static long nCr_RangeSum( long n, long r1,
long r2, long p)
{
long num = 1, den = 1;
long sum = 0;
if (r1 == 0)
sum += 1;
for ( int i = 0; i < r2; i++)
{
num = (num * (n - i)) % p;
den = (den * (i + 1)) % p;
if (i - r1 >= -1 && (i - r1 + 1) % 2 == 0)
{
sum += (num * mod_power(
den, p - 2, p)) % p;
sum %= p;
}
}
return sum;
}
static long compute( string A, string B, int N)
{
int c0A = 0, c1A = 0, c0B = 0, c1B = 0;
foreach ( char c in A)
{
if (c == '1' )
c1A += 1;
else if (c == '0' )
c0A += 1;
}
foreach ( char c in B)
{
if (c == '1' )
c1B += 1;
else if (c == '0' )
c0B += 1;
}
int max1xor = Math.Min(c0A, c1B) +
Math.Min(c1A, c0B);
int min1xor = N - Math.Min(c0B, c0A) -
Math.Min(c1A, c1B);
long ans = nCr_RangeSum(N, min1xor,
max1xor, 1000000000 + 7);
return ans;
}
static public void Main()
{
int N = 3;
string A = "010" ;
string B = "100" ;
Console.WriteLine(compute(A, B, N));
}
}
|
Javascript
function power(a, b, mod)
{
var aa = 1n;
while (b) {
if (BigInt(b) & 1n) {
aa = aa * a;
aa %= mod;
}
a = a * a;
a %= mod;
b = Math.floor(Number(BigInt(b) / 2n));
}
return aa;
}
function nCrRangeSum(n, r1, r2, p)
{
var num = 1n;
var den = 1n;
var sum = 0n;
if (r1 == 0)
sum += 1n;
for ( var i = 0; i < r2; i++) {
num = (num * (BigInt(n) - BigInt(i))) % p;
den = BigInt(den * (BigInt(i) + 1n)) % p;
if (i - r1 >= -1 && (i - r1 + 1) % 2 == 0) {
sum += BigInt(num * power(den, p - 2n, p)) % p;
sum %= p;
}
}
return Number(sum);
}
function compute(A, B, N)
{
var c0A = 0;
var c1A = 0;
var c0B = 0;
var c1B = 0;
for ( var c of A) {
if (c == '1' )
c1A += 1;
else if (c == '0' )
c0A += 1;
}
for ( var c of B) {
if (c == '1' )
c1B += 1;
else if (c == '0' )
c0B += 1;
}
var max1xor = Math.min(c0A, c1B) + Math.min(c1A, c0B);
var min1xor
= N - Math.min(c0B, c0A) - Math.min(c1A, c1B);
var ans = nCrRangeSum(N, min1xor, max1xor,
BigInt(1000000000 + 7));
return ans;
}
var N = 3;
var A = "010" ;
var B = "100" ;
console.log(compute(A, B, N));
|
Time Complexity : O( N )
Space Complexity : O( 1 )
Share your thoughts in the comments
Please Login to comment...