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
Output
485 164
Time Complexity: O(N)
Auxiliary Space: O(N)
Related Articles: