Horje
Count number of pairs of arrays (a, b) such that a[i] <= b[i]

Given two integers n and m, the task is to count the number of pairs of arrays (a, b) where both arrays have a length of m, contain integers between 1 and n (inclusive), and satisfy the conditions that each element in array a is less than or equal to the corresponding element in array b for all indices from 1 to m (i.e, a[i] <= b[i]) Additionally, array a must be sorted in non-decreasing order, array b must be sorted in non-increasing order, and the result should be printed modulo 10^9 + 7.

Example:

Input: n = 2, m = 2
Output: 5
Explanation: There are 5 suitable arrays:

  • a={1,1}, b={2,2}
  • a={1,2}, b={2,2}
  • a={2,2}, b={2,2}
  • a={1,1}, b={2,1}
  • a={1,1}, b={1,1}

Input: n = 10, m = 1
Output: 55

Approach:

This is a combinatorics problem that can be solved using the concept of “Stars and Bars”.

Imagine you have n items (stars) and you want to distribute them into 2m bins (bars). Each bin represents a position in the array a or b. The problem is equivalent to arranging these stars and bars in a line.

The total number of ways to arrange n stars and 2m bars is given by the formula for combinations:

C(n+2m,2m)= (n + 2m)! / (n!(2m)!)

However, since we have n items and 2m bins, and we subtract 1 because the problem states that each element of both arrays is an integer between 1 and n (inclusive), the formula becomes:

C(2m+n-1,2m)= (2m + n – 1)! / (n – 1) ! (2m)!

This gives the total number of ways to distribute the items. However, this count includes duplicates due to the sorted order of a and b. To adjust for these duplicates, we divide by (n-1)! and (2m)!.

Steps-by-step approach:

  • Create a power function to efficiently calculate the modular exponentiation of a number.
  • Calculate factorials for a range of numbers using the calculateFactorial() function.
  • Implement an inverse function to find the modular inverse of a number.
  • In the main function:
    • Precompute factorials.
    • Calculate the answer (2m + n – 1)! represents the total arrangements of elements in arrays a and b
    • Dividing answer by factorial(n-1):
      • This step accounts for the duplicates introduced by the non-decreasing order in array ‘a’. We divide by (n-1)! to eliminate arrangements that would be considered the same due to the sorted order of ‘a’.
    • Dividing by factorial(2m)!:
      • Similar to the above step, this division is for the duplicates introduced by the non-increasing order in array ‘b’. We divide by (2m)! to remove arrangements that would be considered equivalent due to the sorted order of ‘b’.
    • Print the answer modulo 1e9 + 7.

Below is the implementation of the above approach:

C++
#include <bits/stdc++.h>
using namespace std;

// Define the type long long as ll for convenience
typedef long long ll;

// Constants for the modulo operation and the maximum size
// of the array
const ll MODULO = 1e9 + 7;
const ll MAX_SIZE = 2005;

// Function to calculate the power of a number with modulo
ll power(ll base, ll exponent, ll modulo)
{
    base %= modulo;
    ll result = 1;
    while (exponent > 0) {
        if (exponent & 0x1)
            result = (result * base) % modulo;
        base = (base * base) % modulo;
        exponent >>= 1;
    }
    return result;
}

// Array to store the factorial of numbers
ll factorial[MAX_SIZE];

// Function to calculate the factorial of numbers
void calculateFactorial()
{
    factorial[0] = factorial[1] = 1LL;
    for (int i = 2; i < MAX_SIZE; i++)
        factorial[i] = factorial[i - 1] * i % MODULO;
}

// Function to calculate the inverse of a number with modulo
ll inverse(ll x) { return power(x, MODULO - 2, MODULO); }

int main()
{
    // Calculate the factorial of numbers
    calculateFactorial();

    // Variables to store the input numbers and the answer
    ll n = 2, m = 2;

    // Calculate the answer
    ll answer = factorial[2 * m + n - 1];

    // Dividing by (n-1)! and (2m)!: Adjusts for duplicates
    // due to sorted orders of 'a' and 'b'.
    answer = (answer * inverse(factorial[n - 1])) % MODULO;
    answer = (answer * inverse(factorial[2 * m])) % MODULO;

    // Print the answer
    cout << answer;

    return 0;
}
Java
import java.util.Arrays;

public class Main {
    // Define the type long long as ll for convenience
    static class Pair {
        long first, second;

        Pair(long first, long second) {
            this.first = first;
            this.second = second;
        }
    }

    // Constants for the modulo operation and the maximum size
    // of the array
    static final long MODULO = 1000000007;
    static final int MAX_SIZE = 2005;

    // Function to calculate the power of a number with modulo
    static long power(long base, long exponent, long modulo) {
        base %= modulo;
        long result = 1;
        while (exponent > 0) {
            if ((exponent & 1) == 1)
                result = (result * base) % modulo;
            base = (base * base) % modulo;
            exponent >>= 1;
        }
        return result;
    }

    // Array to store the factorial of numbers
    static long[] factorial = new long[MAX_SIZE];

    // Function to calculate the factorial of numbers
    static void calculateFactorial() {
        factorial[0] = factorial[1] = 1L;
        for (int i = 2; i < MAX_SIZE; i++)
            factorial[i] = (factorial[i - 1] * i) % MODULO;
    }

    // Function to calculate the inverse of a number with modulo
    static long inverse(long x) {
        return power(x, MODULO - 2, MODULO);
    }

    public static void main(String[] args) {
        // Calculate the factorial of numbers
        calculateFactorial();

        // Variables to store the input numbers and the answer
        long n = 2, m = 2;

        // Calculate the answer
        long answer = factorial[(int) (2 * m + n - 1)];

        // Dividing by (n-1)! and (2m)!: Adjusts for duplicates
        // due to sorted orders of 'a' and 'b'.
        answer = (answer * inverse(factorial[(int) (n - 1)])) % MODULO;
        answer = (answer * inverse(factorial[(int) (2 * m)])) % MODULO;

        // Print the answer
        System.out.println(answer);
    }
}
C#
using System;

class Program
{
    // Define the type long long as ll for convenience
    public static long Power(long baseValue, long exponent, long modulo)
    {
        baseValue %= modulo;
        long result = 1;
        while (exponent > 0)
        {
            if ((exponent & 0x1) == 1)
                result = (result * baseValue) % modulo;
            baseValue = (baseValue * baseValue) % modulo;
            exponent >>= 1;
        }
        return result;
    }

    // Constants for the modulo operation and the maximum size
    // of the array
    public const long MODULO = 1000000007;
    public const int MAX_SIZE = 2005;

    // Array to store the factorial of numbers
    public static long[] Factorial;

    // Function to calculate the factorial of numbers
    public static void CalculateFactorial()
    {
        Factorial = new long[MAX_SIZE];
        Factorial[0] = Factorial[1] = 1L;
        for (int i = 2; i < MAX_SIZE; i++)
            Factorial[i] = (Factorial[i - 1] * i) % MODULO;
    }

    // Function to calculate the inverse of a number with modulo
    public static long Inverse(long x) => Power(x, MODULO - 2, MODULO);

    static void Main()
    {
        // Calculate the factorial of numbers
        CalculateFactorial();

        // Variables to store the input numbers and the answer
        long n = 2, m = 2;

        // Calculate the answer
        long answer = Factorial[2 * m + n - 1];

        // Dividing by (n-1)! and (2m)!: Adjusts for duplicates
        // due to sorted orders of 'a' and 'b'.
        answer = (answer * Inverse(Factorial[n - 1])) % MODULO;
        answer = (answer * Inverse(Factorial[2 * m])) % MODULO;

        // Print the answer
        Console.WriteLine(answer);
    }
}
JavaScript
// Define the modulo operation
const MODULO = BigInt(1e9 + 7);
const MAX_SIZE = 2005;

// Function to calculate the power of a number with modulo
function power(base, exponent, modulo) {
    base = base % modulo;
    let result = BigInt(1);
    while (exponent > BigInt(0)) {
        if (exponent & BigInt(1))
            result = (result * base) % modulo;
        base = (base * base) % modulo;
        exponent >>= BigInt(1);
    }
    return result;
}

// Array to store the factorial of numbers
let factorial = new Array(MAX_SIZE);

// Function to calculate the factorial of numbers
function calculateFactorial() {
    factorial[0] = factorial[1] = BigInt(1);
    for (let i = 2; i < MAX_SIZE; i++)
        factorial[i] = (factorial[i - 1] * BigInt(i)) % MODULO;
}

// Function to calculate the inverse of a number with modulo
function inverse(x) { return power(x, MODULO - BigInt(2), MODULO); }

// Calculate the factorial of numbers
calculateFactorial();

// Variables to store the input numbers and the answer
let n = BigInt(2), m = BigInt(2);

// Calculate the answer
let answer = factorial[BigInt(2) * m + n - BigInt(1)];

// Dividing by (n-1)! and (2m)!: Adjusts for duplicates
// due to sorted orders of 'a' and 'b'.
answer = (answer * inverse(BigInt(factorial[BigInt(2) * m]))) % MODULO;
answer = (answer * inverse(BigInt(factorial[n - BigInt(1)]))) % MODULO;

// Print the answer
console.log(answer.toString());
Python3
# Function to calculate the power of a number with modulo
def power(base, exponent, modulo):
    base %= modulo
    result = 1
    while exponent > 0:
        if exponent & 1:
            result = (result * base) % modulo
        base = (base * base) % modulo
        exponent >>= 1
    return result

# Constants for the modulo operation and the maximum size of the array
MODULO = 1000000007
MAX_SIZE = 2005

# Array to store the factorial of numbers
factorial = [0] * MAX_SIZE

# Function to calculate the factorial of numbers
def calculate_factorial():
    factorial[0] = factorial[1] = 1
    for i in range(2, MAX_SIZE):
        factorial[i] = (factorial[i - 1] * i) % MODULO

# Function to calculate the inverse of a number with modulo
def inverse(x):
    return power(x, MODULO - 2, MODULO)

# Calculate the factorial of numbers
calculate_factorial()

# Variables to store the input numbers and the answer
n = 2
m = 2

# Calculate the answer
answer = factorial[2 * m + n - 1]

# Dividing by (n-1)! and (2m)! to adjust for duplicates
# due to sorted orders of 'a' and 'b'.
answer = (answer * inverse(factorial[n - 1])) % MODULO
answer = (answer * inverse(factorial[2 * m])) % MODULO

# Print the answer
print(answer)

Output
5

Time Complexity: O(MAX_SIZE * log(exponent)), Computing factorials involves iterating up to MAX_SIZE, and modular exponentiation has a time complexity proportional to log(exponent).
Auxiliary Space: O(MAX_SIZE), The program uses an array (factorial) with a fixed size (MAX_SIZE).




Reffered: https://www.geeksforgeeks.org


Arrays

Related
Rearrange arrays such that sum of corresponding elements is same for all equal indices Rearrange arrays such that sum of corresponding elements is same for all equal indices
Minimum Increments to reach the given MEX Minimum Increments to reach the given MEX
Subarrays, Subsequences, and Subsets in Array Subarrays, Subsequences, and Subsets in Array
Implement Arrays in different Programming Languages Implement Arrays in different Programming Languages
Range Minimum Query with Range Assignment Range Minimum Query with Range Assignment

Type:
Geek
Category:
Coding
Sub Category:
Tutorial
Uploaded by:
Admin
Views:
17