Ways to select one or more pairs from two different sets

Given two positive numbers β€˜n’ and β€˜m’ (n <= m) which represent total number of items of first and second type of sets respectively. Find total number of ways to select at-least one pair by picking one item from first type(I) and another item from second type(II). In any arrangement, an item should not be common between any two pairs. Note: Since answer can be large, output it in modulo 1000000007.

Input: 2 2
Output: 6
Explanation
Let's denote the items of I type
as a, b and II type as c, d i.e,
Type I -  a, b
Type II - c, d
Ways to arrange one pair at a time
1. a --- c
2. a --- d
3. b --- c
4. b --- d
Ways to arrange two pairs at a time
5. a --- c, b --- d
6. a --- d, b --- c

Input: 2 3
Output: 12

Input: 1 2
Output: 2

The approach is simple, we only need the combination of choosing β€˜iβ€˜ items from β€˜nβ€˜ type and β€˜iβ€˜ items from β€˜mβ€˜ type and multiply them(Rule of product) where β€˜iβ€˜ varies from 1 to β€˜nβ€˜. But we can also permute the resultant product in β€˜i’ ways therefore we need to multiply with i!. After that take the sum(Rule of sum) of all resultant product to get the final answer.

[Tex]\implies\displaystyle \sum_{i=1}^{\text{n}} \frac{n!}{i!(n-i)!}\cdot \frac{m!}{i!(m-i)!}\cdot i![/Tex][Tex]\implies\displaystyle\sum_{i=1}^{\text{n}} \frac{{}^n\text P_i\cdot{}^m\text P_i}{i}[/Tex]

C++


                    

Java


                    

Python3


                    

Javascript


                    

C#

// C# program to find total no. of ways
// to form a pair in two different set
using System;
 
class Program {
    static readonly long mod = 1000000007;
    //Iterative Function to calculate (x^y)%p in O(log y)
    static long Power(long x, long y, long p) {
        long res = 1; // Initialize result
        x %= p; // Update x if it is more than or equal to p
 
        // If y is odd, multiply x with result
        while (y > 0) {
            if ((y & 1) == 1) {
                res = (res * x) % p;
            }
             
            // y must be even now
            y >>= 1;
            x = (x * x) % p;
        }
 
        return res;
    }
 
    // Pre-calculate factorial and Inverse of number
    static (long[], long[]) PreCalculate(int n) {
        long[] fact = new long[n + 1];
        long[] inverseMod = new long[n + 1];
 
        fact[0] = inverseMod[0] = 1;
 
        for (int i = 1; i <= n; i++) {
            fact[i] = (fact[i - 1] * i) % mod;
            inverseMod[i] = Power(fact[i], mod - 2, mod);
        }
 
        return (fact, inverseMod);
    }
 
    // utility function to calculate nCr
    static long nPr(int a, int b, long[] fact, long[] inverseMod) {
        return (fact[a] * inverseMod[a - b]) % mod;
    }
 
    static int CountWays(int n, int m) {
        // Pre-calculate factorial and inverse of number
        (long[] fact, long[] inverseMod) = PreCalculate(m);
 
        // Initialize answer
        long ans = 0;
 
        for (int i = 1; i <= n; i++) {
            ans += (((nPr(n, i, fact, inverseMod)
                      * nPr(m, i, fact, inverseMod)) % mod)
                    * inverseMod[i]) % mod;
 
            if (ans >= mod) {
              ans %= mod;
            }
        }
 
        return (int)ans;
    }
    // Derive code
    static void Main(string[] args) {
        int n = 2;
        int m = 2;
        Console.WriteLine(CountWays(n, m));
    }
}
 
// This code is contributed by Shivhack999

                    

Output:

6

Time complexity: O(m*log(mod)) Auxiliary space: O(m)