An application on Bertrand’s ballot theorem

Given the number of ‘X’ and ‘Y’ in a string which consists of characters from the set {‘X’, ‘Y’}, the task is to find the number of permutations which satisfy the condition where every sub-string of the permutation starting from the first character has count(‘X’) > count(‘Y’). Print the answer modulo 1000000007. Note that the number of ‘X’ will always be greater than number of ‘Y’ in the given string.

Examples:

Input: X = 2, Y = 1
Output: 1
The possible distributions are “XYX”, “XXY” and “YXX”
Distribution 1: Till 1st index (X = 1, Y = 0), till 2nd index (X = 1, Y = 1) and till 3rd index (X = 2, Y = 1). Number of X isn’t always greater than Y so this distribution is not valid.
Distribution 2: 1st index (X = 1, Y = 0), 2nd index (X = 2, Y = 0) and 3rd index (X = 2, Y = 1). This is a valid distribution as X is always greater than Y.
Distribution 3: 1st index (X = 0, Y = 1), 2nd index (X = 1, Y = 1) and 3rd index (X = 2, Y = 1). Invalid distribution.

Input: X = 3, Y = 1
Output: 1

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: This type of problem can be solved by Bertrand’s Ballot Theorem. Out of all possible distributions, the probability that X always remains in the lead is (X – Y) / (X + Y). And the total number of distributions are (X + Y)! / (X! * Y!). Hence the distributions in which X always has the lead are (X + Y – 1)! * (X – Y) / (X! * Y!).
For calculating (X + Y – 1)! * (X – Y) / (X! * Y!), we need to calculate multiplicative modular inverse of X! and thus similarly for Y. Since 1000000007 is a prime, according to Fermat’s Little Theorem : (1 / X!) % 1000000007 = ((X!)(1000000007 – 2)) % 1000000007. Similar result also holds for Y.

Below is the implementation of the above approach:

C++

 `// C++ implementation of the approach ` `#include ` `using` `namespace` `std; ` `#define ll long long ` ` `  `ll mod = 1000000007; ` `ll arr[1000001] = { 0 }; ` ` `  `// Function to calculate factorial ` `// of a number mod 1000000007 ` `void` `cal_factorial() ` `{ ` `    ``arr[0] = 1; ` ` `  `    ``// Factorial of i = factorial of (i - 1) * i; ` `    ``for` `(``int` `i = 1; i <= 1000000; i++) { ` ` `  `        ``// Taking mod along with calculation. ` `        ``arr[i] = (arr[i - 1] * i) % mod; ` `    ``} ` `} ` ` `  `// Function for modular exponentiation ` `ll mod_exponent(ll num, ll p) ` `{ ` ` `  `    ``if` `(p == 0) ` `        ``return` `1; ` ` `  `    ``// If p is odd ` `    ``if` `(p & 1) { ` `        ``return` `((num % mod) ` `                ``* (mod_exponent((num * num) % mod, p / 2)) ` `                ``% mod) ` `               ``% mod; ` `    ``} ` ` `  `    ``// If p is even ` `    ``else` `if` `(!(p & 1)) ` `        ``return` `(mod_exponent((num * num) % mod, p / 2)) ` `               ``% mod; ` `} ` ` `  `// Function to return the count of ` `// required permutations ` `ll getCount(ll x, ll y) ` `{ ` `    ``ll ans = arr[x + y - 1]; ` ` `  `    ``// Calculating multiplicative modular inverse ` `    ``// for x! and multiplying with ans ` `    ``ans *= mod_exponent(arr[x], mod - 2); ` `    ``ans %= mod; ` ` `  `    ``// Calculating multiplicative modular inverse ` `    ``// for y! and multiplying with ans ` `    ``ans *= mod_exponent(arr[y], mod - 2); ` `    ``ans %= mod; ` ` `  `    ``ans *= (x - y); ` `    ``ans %= mod; ` `    ``return` `ans; ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` ` `  `    ``// Pre-compute factorials ` `    ``cal_factorial(); ` ` `  `    ``ll x = 3, y = 1; ` `    ``cout << getCount(x, y); ` ` `  `    ``return` `0; ` `} `

Java

 `// Java implementation of the approach ` `class` `GFG ` `{ ` `     `  `static` `long` `mod = ``1000000007``; ` `static` `long``[] arr = ``new` `long``[``1000001``]; ` ` `  `// Function to calculate factorial ` `// of a number mod 1000000007 ` `static` `void` `cal_factorial() ` `{ ` `    ``arr[``0``] = ``1``; ` ` `  `    ``// Factorial of i = factorial of (i - 1) * i; ` `    ``for` `(``int` `i = ``1``; i <= ``1000000``; i++)  ` `    ``{ ` ` `  `        ``// Taking mod along with calculation. ` `        ``arr[i] = ((arr[i - ``1``] * i) % mod); ` `    ``} ` `} ` ` `  `// Function for modular exponentiation ` `static` `long` `mod_exponent(``long` `num, ``long` `p) ` `{ ` ` `  `    ``if` `(p == ``0``) ` `        ``return` `1``; ` ` `  `    ``// If p is odd ` `    ``if` `((p & ``1``) != ``0``)  ` `    ``{ ` `        ``return` `((num % mod) ` `                ``* (mod_exponent((num * num) % mod, p / ``2``)) ` `                ``% mod) ` `            ``% mod; ` `    ``} ` ` `  `    ``// If p is even ` `    ``else` `        ``return` `(mod_exponent((num * num) % mod, p / ``2``)) ` `            ``% mod; ` `} ` ` `  `// Function to return the count of ` `// required permutations ` `static` `long` `getCount(``long` `x, ``long` `y) ` `{ ` `    ``long` `ans = arr[(``int``)x + (``int``)y - ``1``]; ` ` `  `    ``// Calculating multiplicative modular inverse ` `    ``// for x! and multiplying with ans ` `    ``ans *= mod_exponent(arr[(``int``)x], mod - ``2``); ` `    ``ans %= mod; ` ` `  `    ``// Calculating multiplicative modular inverse ` `    ``// for y! and multiplying with ans ` `    ``ans *= mod_exponent(arr[(``int``)y], mod - ``2``); ` `    ``ans %= mod; ` ` `  `    ``ans *= (x - y); ` `    ``ans %= mod; ` `    ``return` `ans; ` `} ` ` `  `// Driver code ` `public` `static` `void` `main (String[] args) ` `{ ` ` `  `    ``// Pre-compute factorials ` `    ``cal_factorial(); ` ` `  `    ``long` `x = ``3``, y = ``1``; ` `    ``System.out.println(getCount(x, y)); ` `} ` `} ` ` `  `// This code is contributed by chandan_jnu `

Python3

 `# Python3 implementation of the approach ` `mod ``=` `1000000007` `arr ``=` `[``0``] ``*` `(``1000001``)  ` ` `  `# Function to calculate factorial ` `# of a number mod 1000000007 ` `def` `cal_factorial(): ` ` `  `    ``arr[``0``] ``=` `1` ` `  `    ``# Factorial of i = factorial  ` `    ``# of (i - 1) * i ` `    ``for` `i ``in` `range``(``1``, ``1000001``):  ` `         `  `        ``# Taking mod along with calculation. ` `        ``arr[i] ``=` `(arr[i ``-` `1``] ``*` `i) ``%` `mod ` `     `  `# Function for modular exponentiation ` `def` `mod_exponent(num, p): ` ` `  `    ``if` `(p ``=``=` `0``): ` `        ``return` `1` ` `  `    ``# If p is odd ` `    ``if` `(p & ``1``) : ` `        ``return` `((num ``%` `mod)``*` `(mod_exponent((num ``*` `num) ``%`  `                              ``mod, p ``/``/` `2``)) ``%` `mod) ``%` `mod ` `     `  `    ``# If p is even ` `    ``elif` `(``not``(p & ``1``)): ` `        ``return` `(mod_exponent((num ``*` `num) ``%`  `                              ``mod, p ``/``/` `2``))``%` `mod ` ` `  `# Function to return the count of ` `# required permutations ` `def` `getCount(x, y): ` ` `  `    ``ans ``=` `arr[x ``+` `y ``-` `1``] ` ` `  `    ``# Calculating multiplicative modular inverse ` `    ``# for x! and multiplying with ans ` `    ``ans ``*``=` `mod_exponent(arr[x], mod ``-` `2``) ` `    ``ans ``%``=` `mod ` ` `  `    ``# Calculating multiplicative modular inverse ` `    ``# for y! and multiplying with ans ` `    ``ans ``*``=` `mod_exponent(arr[y], mod ``-` `2``) ` `    ``ans ``%``=` `mod ` ` `  `    ``ans ``*``=` `(x ``-` `y) ` `    ``ans ``%``=` `mod ` `    ``return` `ans ` `     `  `# Driver Code ` `if` `__name__ ``=``=` `'__main__'``: ` `     `  `    ``# Pre-compute factorials ` `    ``cal_factorial() ` ` `  `    ``x ``=` `3` `    ``y ``=` `1` `    ``print``(getCount(x, y)) ` ` `  `# This code is contributed by ` `# SHUBHAMSINGH10 `

C#

 `// C# implementation of the approach ` `class` `GFG ` `{ ` `static` `long` `mod = 1000000007; ` `static` `long``[] arr=``new` `long``[1000001]; ` ` `  `// Function to calculate factorial ` `// of a number mod 1000000007 ` `static` `void` `cal_factorial() ` `{ ` `    ``arr[0] = 1; ` ` `  `    ``// Factorial of i = factorial of (i - 1) * i; ` `    ``for` `(``long` `i = 1; i <= 1000000; i++)  ` `    ``{ ` ` `  `        ``// Taking mod along with calculation. ` `        ``arr[i] = (arr[i - 1] * i) % mod; ` `    ``} ` `} ` ` `  `// Function for modular exponentiation ` `static` `long` `mod_exponent(``long` `num, ``long` `p) ` `{ ` ` `  `    ``if` `(p == 0) ` `        ``return` `1; ` ` `  `    ``// If p is odd ` `    ``if` `((p & 1)!=0)  ` `    ``{ ` `        ``return` `((num % mod) ` `                ``* (mod_exponent((num * num) % mod, p / 2)) ` `                ``% mod) ` `            ``% mod; ` `    ``} ` ` `  `    ``// If p is even ` `    ``else` `        ``return` `(mod_exponent((num * num) % mod, p / 2)) ` `            ``% mod; ` `} ` ` `  `// Function to return the count of ` `// required permutations ` `static` `long` `getCount(``long` `x, ``long` `y) ` `{ ` `    ``long` `ans = arr[x + y - 1]; ` ` `  `    ``// Calculating multiplicative modular inverse ` `    ``// for x! and multiplying with ans ` `    ``ans *= mod_exponent(arr[x], mod - 2); ` `    ``ans %= mod; ` ` `  `    ``// Calculating multiplicative modular inverse ` `    ``// for y! and multiplying with ans ` `    ``ans *= mod_exponent(arr[y], mod - 2); ` `    ``ans %= mod; ` ` `  `    ``ans *= (x - y); ` `    ``ans %= mod; ` `    ``return` `ans; ` `} ` ` `  `// Driver code ` `static` `void` `Main() ` `{ ` ` `  `    ``// Pre-compute factorials ` `    ``cal_factorial(); ` ` `  `    ``long` `x = 3, y = 1; ` `    ``System.Console.WriteLine(getCount(x, y)); ` `} ` `} ` ` `  `// This code is contributed by chandan_jnu `

PHP

 ` `

Output:

```2
```

My Personal Notes arrow_drop_up

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.