Given integers A, B, C, and D, There are two boxes First Box has A red balls and B blue balls and the second box has C red balls and D blue balls, the task is to count ways to select 3 red balls and 3 blue balls so that there are 3 balls drawn from the first box and 3 balls drawn from the second box. (Print the answer modulo 109 + 7).
Examples:
Input: A = 4, B =3, C = 3, D = 4
Output: 485Input: A = 3, B = 3, C = 3, D = 3
Output: 164
Naive approach: The basic way to solve the problem is as follows:
The basic way to solve this problem is to generate all possible combinations by using a recursive approach.
Time Complexity: O(N!)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized based on the following idea:
The problem can be solved with combinatorics:
Case 1: 2 red balls and 1 blue ball from box 1 and 1 red ball and 2 blue balls from box 2.
- Total ways of case1 = AC2 * BC1 * CC1 * DC2
Case 2: 3 red balls from box 1 and 3 blue balls from box 2.
- Total ways of case2 = AC3 * DC3
Case 3: 3 blue balls from box1 and 3 red balls from box 2
- Total ways of case3 = BC3 * CC3
Case 4: 1 red ball and 2 blue balls from box 1 and 2 red balls and 1 blue ball from box 2.
- Total ways of case4 = AC1 * BC2 * CC2 * DC1
Total ways = Total ways of case1 + Total ways of case2 + Total ways of case3 + Total ways of case 3 + Total ways of case4
instead of dividing factorials we multiply their modular multiplicative inverses.
Follow the steps below to solve the problem:
- Initializing fact[] array and Precomputing all factorials from 1 to 100000.
- initializing ANS variable.
- Calculating the answer by using the above formula.
- Print the answer.
Below is the implementation of the above approach:
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// to avoid integer overflow #define int long long const int MOD = 1e9 + 7;
// To find GCD of a and b int gcd( int a, int b);
// To compute x raised to power y under // modulo M int power( int x, unsigned int y, unsigned int M);
// Function to find modular inverse of // under modulo M // Assumption: M is prime int modInverse( int A, int M)
{ int g = gcd(A, M);
return power(A, M - 2, M);
} // To compute x^y under modulo m int power( int x, unsigned int y, unsigned int M)
{ if (y == 0)
return 1;
int p = power(x, y / 2, M) % M;
p = (p * p) % M;
return (y % 2 == 0) ? p : (x * p) % M;
} // Function to return gcd of a and b int gcd( int a, int b)
{ if (a == 0)
return b;
return gcd(b % a, a);
} // Function to Count number of ways // of taking 3 red balls and 3 blue // balls so that 3 balls are from box1 // and 3 balls are from box 2 int countWays( int A, int B, int C, int D)
{ // Precomputation array storing
// factorials MOD 1e9 + 7
int fact[100001];
// Initialize the base elements
fact[1] = 1, fact[0] = 1;
// Filling factorial table
for ( int i = 2; i <= 100000; i++) {
fact[i] = (fact[i - 1] * i) % MOD;
}
// case 1 multiplying A!/(A-2)!
int ans1
= (fact[A] * modInverse(fact[A - 2], MOD)) % MOD;
// case 1 multiplying B!/(B-1)!
ans1 = (ans1 * fact[B] * modInverse(fact[B - 1], MOD))
% MOD;
// case 1 taking into account C!/(C-1)!
ans1 = (ans1 * fact[C] * modInverse(fact[C - 1], MOD))
% MOD;
// case 1 taking into account D!/(D-1)!
ans1 = (ans1 * fact[D] * modInverse(fact[D - 2], MOD))
% MOD;
// case 1 taking into account / 4
ans1 = (ans1 * modInverse(4, MOD)) % MOD;
// case 2 multiplying A!/(A-3)!
int ans2
= (fact[A] * modInverse(fact[A - 3], MOD)) % MOD;
// case 2 multiplying D!/(D-3)!
ans2 = (ans2 * fact[D] * modInverse(fact[D - 3], MOD))
% MOD;
// case 2 taking into account / 36
ans2 = (ans2 * modInverse(36, MOD)) % MOD;
// case 3 multiplying B!/(B-3)!
int ans3
= (fact[B] * modInverse(fact[B - 3], MOD)) % MOD;
// case 3 multiplying C!/(C-3)!
ans3 = (ans3 * fact[C] * modInverse(fact[C - 3], MOD))
% MOD;
// case 3 taking into account / 36
ans3 = (ans3 * modInverse(36, MOD)) % MOD;
// case 4 multiplying A!/(A-1)!
int ans4
= (fact[A] * modInverse(fact[A - 1], MOD)) % MOD;
// case 4 multiplying B!/(B-2)!
ans4 = (ans4 * fact[B] * modInverse(fact[B - 2], MOD))
% MOD;
// case 4 taking into account C!/(C-2)!
ans4 = (ans4 * fact[C] * modInverse(fact[C - 2], MOD))
% MOD;
// case 4 taking into account D!/(D-1)!
ans4 = (ans4 * fact[D] * modInverse(fact[D - 1], MOD))
% MOD;
// case 4 taking into accont / 4
ans4 = (ans4 * modInverse(4, MOD)) % MOD;
// answer
int ans = (ans1 + ans2 + ans3 + ans4) % MOD;
// Returning the answer
return ans;
} // Driver Code int32_t main() { // Input 1
int A = 4, B = 3, C = 3, D = 4;
// Function Call
cout << countWays(A, B, C, D) << endl;
// Input 2
int A1 = 3, B1 = 3, C1 = 3, D1 = 3;
// Function Call
cout << countWays(A1, B1, C1, D1) << endl;
return 0;
} |
// Java code for the above approach import java.io.*;
class GFG {
static final int MOD = ( int )1e9 + 7 ;
// To find GCD of a and b
static int gcd( int a, int b)
{
if (a == 0 )
return b;
return gcd(b % a, a);
}
// To compute x raised to power y under modulo M
static int power( int x, int y, int M)
{
if (y == 0 )
return 1 ;
int p = power(x, y / 2 , M) % M;
p = ( int )(( long )p * p % M);
return (y % 2 == 0 ) ? p : ( int )(( long )x * p % M);
}
// Function to find modular inverse of A under modulo M
// Assumption: M is prime
static int modInverse( int A, int M)
{
int g = gcd(A, M);
return power(A, M - 2 , M);
}
// Function to Count number of ways
// of taking 3 red balls and 3 blue
// balls so that 3 balls are from box1
// and 3 balls are from box 2
static int countWays( int A, int B, int C, int D)
{
// Precomputation array storing factorials MOD 1e9 +
// 7
int [] fact = new int [ 100001 ];
// Initialize the base elements
fact[ 1 ] = 1 ;
fact[ 0 ] = 1 ;
// Fill factorial table
for ( int i = 2 ; i <= 100000 ; i++) {
fact[i] = ( int )(( long )fact[i - 1 ] * i % MOD);
}
// case 1 multiplying A!/(A-2)!
int ans1
= ( int )(( long )fact[A]
* modInverse(fact[A - 2 ], MOD) % MOD);
// case 1 multiplying B!/(B-1)!
ans1 = ( int )(( long )ans1 * fact[B] % MOD
* modInverse(fact[B - 1 ], MOD) % MOD);
// case 1 taking into account C!/(C-1)!
ans1 = ( int )(( long )ans1 * fact[C] % MOD
* modInverse(fact[C - 1 ], MOD) % MOD);
// case 1 taking into account D!/(D-1)!
ans1 = ( int )(( long )ans1 * fact[D] % MOD
* modInverse(fact[D - 2 ], MOD) % MOD);
// case 1 taking into account / 4
ans1 = ( int )(( long )ans1 * modInverse( 4 , MOD) % MOD);
// case 2 multiplying A!/(A-3)!
int ans2
= ( int )(( long )fact[A]
* modInverse(fact[A - 3 ], MOD) % MOD);
// case 2 multiplying D!/(D-3)!
ans2 = ( int )(( long )ans2 * fact[D] % MOD
* modInverse(fact[D - 3 ], MOD) % MOD);
// case 2 taking into account / 36
ans2
= ( int )(( long )ans2 * modInverse( 36 , MOD) % MOD);
// case 3 multiplying B!/(B-3)!
int ans3
= ( int )(( long )fact[B]
* modInverse(fact[B - 3 ], MOD) % MOD);
// case 3 multiplying C!/(C-3)!
ans3 = ( int )(( long )ans3 * fact[C] % MOD
* modInverse(fact[C - 3 ], MOD) % MOD);
// case 3 taking into account / 36
ans3
= ( int )(( long )ans3 * modInverse( 36 , MOD) % MOD);
// case 4 multiplying A!/(A-1)!
int ans4
= ( int )(( long )fact[A]
* modInverse(fact[A - 1 ], MOD) % MOD);
// case 4 multiplying B!/(B-2)!
ans4 = ( int )(( long )ans4 * fact[B] % MOD
* modInverse(fact[B - 2 ], MOD) % MOD);
// case 4 taking into account C!/(C-2)!
ans4 = ( int )(( long )ans4 * fact[C] % MOD
* modInverse(fact[C - 2 ], MOD) % MOD);
// case 4 taking into account D!/(D-2)!
ans4 = ( int )(( long )ans4 * fact[D] % MOD
* modInverse(fact[D - 1 ], MOD) % MOD);
// case 4 taking into account / 12
ans4 = ( int )(( long )ans4 * modInverse( 4 , MOD) % MOD);
return (ans1 + ans2 + ans3 + ans4) % MOD;
}
public static void main(String[] args)
{
// Input 1
int A = 4 , B = 3 , C = 3 , D = 4 ;
// Function Call
System.out.println(countWays(A, B, C, D));
// Input 2
int A1 = 3 , B1 = 3 , C1 = 3 , D1 = 3 ;
// Function Call
System.out.println(countWays(A1, B1, C1, D1));
}
} // This code is contributed by lokesh. |
# Python code for the above approach import math
MOD = int ( 1e9 + 7 )
# To find GCD of a and b def gcd(a: int , b: int ) - > int :
if a = = 0 :
return b
return gcd(b % a, a)
# To compute x raised to power y under # modulo M def power(x: int , y: int , M: int ) - > int :
if y = = 0 :
return 1
p = power(x, y / / 2 , M) % M
p = (p * p) % M
return (p if y % 2 = = 0 else (x * p) % M)
# Function to find modular inverse of # under modulo M # Assumption: M is prime def modInverse(A: int , M: int ) - > int :
g = gcd(A, M)
return power(A, M - 2 , M)
# Function to Count number of ways # of taking 3 red balls and 3 blue # balls so that 3 balls are from box1 # and 3 balls are from box 2 def countWays(A: int , B: int , C: int , D: int ) - > int :
# Precomputation array storing
# factorials MOD 1e9 + 7
fact = [ 1 for i in range ( 100001 )]
# Filling factorial table
for i in range ( 2 , 100001 ):
fact[i] = (fact[i - 1 ] * i) % MOD
# case 1 multiplying A!/(A-2)!
ans1 = (fact[A] * modInverse(fact[A - 2 ], MOD)) % MOD
# case 1 multiplying B!/(B-1)!
ans1 = (ans1 * fact[B] * modInverse(fact[B - 1 ], MOD)) % MOD
# case 1 taking into account C!/(C-1)!
ans1 = (ans1 * fact[C] * modInverse(fact[C - 1 ], MOD)) % MOD
# case 1 taking into account D!/(D-1)!
ans1 = (ans1 * fact[D] * modInverse(fact[D - 2 ], MOD)) % MOD
# case 1 taking into account / 4
ans1 = (ans1 * modInverse( 4 , MOD)) % MOD
# case 2 multiplying A!/(A-3)!
ans2 = (fact[A] * modInverse(fact[A - 3 ], MOD)) % MOD
# case 2 multiplying D!/(D-3)!
ans2 = (ans2 * fact[D] * modInverse(fact[D - 3 ], MOD)) % MOD
# case 2 taking into account / 36
ans2 = (ans2 * modInverse( 36 , MOD)) % MOD
# case 3 multiplying B!/(B-3)!
ans3 = (fact[B] * modInverse(fact[B - 3 ], MOD)) % MOD
# case 3 multiplying C!/(C-3)!
ans3 = (ans3 * fact[C] * modInverse(fact[C - 3 ], MOD)) % MOD
# case 3 taking into account / 36
ans3 = (ans3 * modInverse( 36 , MOD)) % MOD
# case 4 multiplying A!/(A-1)!
ans4 = (fact[A] * modInverse(fact[A - 1 ], MOD)) % MOD
# case 4 multiplying B!/(B-2)!
ans4 = (ans4 * fact[B] * modInverse(fact[B - 2 ], MOD)) % MOD
# case 4 taking into account C!/(C-2)!
ans4 = (ans4 * fact[C] * modInverse(fact[C - 2 ], MOD)) % MOD
# case 4 taking into account D!/(D-2)!
ans4 = (ans4 * fact[D] * modInverse(fact[D - 1 ], MOD)) % MOD
# case 4 taking into account / 12
ans4 = (ans4 * modInverse( 4 , MOD)) % MOD
# Return the final answer
return (ans1 + ans2 + ans3 + ans4) % MOD
# Driver code if __name__ = = '__main__' :
A = 4 # Number of red balls in box 1
B = 3 # Number of blue balls in box 1
C = 3 # Number of red balls in box 2
D = 4 # Number of blue balls in box 2
# Function call to find number of ways
print ( int (countWays(A, B, C, D)))
A = 3 # Number of red balls in box 1
B = 3 # Number of blue balls in box 1
C = 3 # Number of red balls in box 2
D = 3 # Number of blue balls in box 2
# Function call to find number of ways
print ( int (countWays(A, B, C, D)))
# This code is contributed by Potta Lokesh |
// C# code to implement the approach using System;
using System.Collections.Generic;
class GFG {
const long MOD = 1000000007;
// Function to return gcd of a and b
static long gcd( long a, long b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
// To compute x^y under modulo m
static long power( long x, long y, long M)
{
if (y == 0)
return 1;
long p = power(x, y / 2, M) % M;
p = (p * p) % M;
return (y % 2 == 0) ? p : (x * p) % M;
}
// Function to find modular inverse of
// under modulo M
// Assumption: M is prime
static long modInverse( long A, long M)
{
long g = gcd(A, M);
return power(A, M - 2, M);
}
// Function to Count number of ways
// of taking 3 red balls and 3 blue
// balls so that 3 balls are from box1
// and 3 balls are from box 2
static long countWays( long A, long B, long C, long D)
{
// Precomputation array storing
// factorials MOD 1e9 + 7
long [] fact= new long [100001];
// Initialize the base elements
fact[1] = 1;
fact[0] = 1;
// Filling factorial table
for ( long i = 2; i <= 100000; i++) {
fact[i] = (fact[i - 1] * i) % MOD;
}
// case 1 multiplying A!/(A-2)!
long ans1
= (fact[A] * modInverse(fact[A - 2], MOD)) % MOD;
// case 1 multiplying B!/(B-1)!
ans1 = (ans1 * fact[B] * modInverse(fact[B - 1], MOD))
% MOD;
// case 1 taking longo account C!/(C-1)!
ans1 = (ans1 * fact[C] * modInverse(fact[C - 1], MOD))
% MOD;
// case 1 taking longo account D!/(D-1)!
ans1 = (ans1 * fact[D] * modInverse(fact[D - 2], MOD))
% MOD;
// case 1 taking longo account / 4
ans1 = (ans1 * modInverse(4, MOD)) % MOD;
// case 2 multiplying A!/(A-3)!
long ans2
= (fact[A] * modInverse(fact[A - 3], MOD)) % MOD;
// case 2 multiplying D!/(D-3)!
ans2 = (ans2 * fact[D] * modInverse(fact[D - 3], MOD))
% MOD;
// case 2 taking longo account / 36
ans2 = (ans2 * modInverse(36, MOD)) % MOD;
// case 3 multiplying B!/(B-3)!
long ans3
= (fact[B] * modInverse(fact[B - 3], MOD)) % MOD;
// case 3 multiplying C!/(C-3)!
ans3 = (ans3 * fact[C] * modInverse(fact[C - 3], MOD))
% MOD;
// case 3 taking longo account / 36
ans3 = (ans3 * modInverse(36, MOD)) % MOD;
// case 4 multiplying A!/(A-1)!
long ans4
= (fact[A] * modInverse(fact[A - 1], MOD)) % MOD;
// case 4 multiplying B!/(B-2)!
ans4 = (ans4 * fact[B] * modInverse(fact[B - 2], MOD))
% MOD;
// case 4 taking longo account C!/(C-2)!
ans4 = (ans4 * fact[C] * modInverse(fact[C - 2], MOD))
% MOD;
// case 4 taking longo account D!/(D-1)!
ans4 = (ans4 * fact[D] * modInverse(fact[D - 1], MOD))
% MOD;
// case 4 taking longo accont / 4
ans4 = (ans4 * modInverse(4, MOD)) % MOD;
// answer
long ans = (ans1 + ans2 + ans3 + ans4) % MOD;
// Returning the answer
return ans;
}
// Driver Code
public static void Main()
{
// Input 1
long A = 4, B = 3, C = 3, D = 4;
// Function Call
Console.Write(countWays(A, B, C, D)+ "\n" );
// Input 2
long A1 = 3, B1 = 3, C1 = 3, D1 = 3;
// Function Call
Console.Write(countWays(A1, B1, C1, D1)+ "\n" );
}
} // This code is contributed by agrawalpoojaa976. |
// Javascript code for the above approach const MOD = BigInt(1e9 + 7); // To find GCD of a and b function gcd(a, b) {
if (a == 0n) {
return b;
}
return gcd(b % a, a);
} // To compute x raised to power y under // modulo M function power(x, y, M) {
if (y == 0n) {
return 1n;
}
let p = power(x, y / 2n, M) % M;
p = (p * p) % M;
return (y % 2n == 0n ? p : (x * p) % M);
} // Function to find modular inverse of // under modulo M // Assumption: M is prime function modInverse(A, M) {
const g = gcd(A, M);
return power(A, M - 2n, M);
} // Function to Count number of ways // of taking 3 red balls and 3 blue // balls so that 3 balls are from box1 // and 3 balls are from box 2 function countWays(A, B, C, D) {
// Precomputation array storing
// factorials MOD 1e9 + 7
const fact = [BigInt(1)];
// Filling factorial table
for (let i = 1n; i <= 100000n; i++) {
fact.push((fact[i - 1n] * i) % MOD);
}
// case 1 multiplying A!/(A-2)!
let ans1 = (fact[A] * modInverse(fact[A - 2n], MOD)) % MOD;
// case 1 multiplying B!/(B-1)!
ans1 = (ans1 * fact[B] * modInverse(fact[B - 1n], MOD)) % MOD;
// case 1 taking into account C!/(C-1)!
ans1 = (ans1 * fact[C] * modInverse(fact[C - 1n], MOD)) % MOD;
// case 1 taking into account D!/(D-1)!
ans1 = (ans1 * fact[D] * modInverse(fact[D - 2n], MOD)) % MOD;
// case 1 taking into account / 4
ans1 = (ans1 * modInverse(4n, MOD)) % MOD;
// case 2 multiplying A!/(A-3)!
let ans2 = (fact[A] * modInverse(fact[A - 3n], MOD)) % MOD;
// case 2 multiplying D!/(D-3)!
ans2 = (ans2 * fact[D] * modInverse(fact[D - 3n], MOD)) % MOD;
// case 2 taking into account / 36
ans2 = (ans2 * modInverse(36n, MOD)) % MOD;
// case 3 multiplying B!/(B-3)!
let ans3 = (fact[B] * modInverse(fact[B - 3n], MOD)) % MOD;
// case 3 multiplying C!/(C-3)!
ans3 = (ans3 * fact[C] * modInverse(fact[C - 3n], MOD)) % MOD;
// case 3 taking into account / 36
ans3 = (ans3 * modInverse(36n, MOD)) % MOD;
// case 4 multiplying A!/(A-1)!
let ans4 = (fact[A] * modInverse(fact[A - 1n], MOD)) % MOD;
// case 4 multiplying B!/(B-2)!
ans4 = (ans4 * fact[B] * modInverse(fact[B - 2n], MOD)) % MOD;
// case 4 taking into account C!/(C-2)!
ans4 = (ans4 * fact[C] * modInverse(fact[C - 2n], MOD)) % MOD;
// case 4 taking into account D!/(D-2)!
ans4 = (ans4 * fact[D] * modInverse(fact[D - 1n], MOD)) % MOD;
// case 4 taking into account / 12
ans4 = (ans4 * modInverse(4n, MOD)) % MOD;
// Return the final answer
return Number((ans1 + ans2 + ans3 + ans4) % MOD);
} // Driver Code console.log(countWays(4n, 3n, 3n, 4n)); console.log(countWays(3n, 3n, 3n, 3n)); // This code is contributed by sdeadityasharma |
485 164
Time Complexity: O(N)
Auxiliary Space: O(N)
Related Articles: