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

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP implementation of the approach
$mod = 1000000007;
$arr = array_fill(0, 10001, 0);
  
// Function to calculate factorial
// of a number mod 1000000007
function cal_factorial()
{
    global $arr, $mod;
    $arr[0] = 1;
  
    // Factorial of i = factorial 
    // of (i - 1) * i;
    for ($i = 1; $i <= 10000; $i++) 
    {
  
        // Taking mod aint with calculation.
        $arr[$i] = ($arr[$i - 1] * $i) % $mod;
    }
}
  
// Function for modular exponentiation
function mod_exponent($num, $p)
{
    global $mod;
    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
function getCount($x, $y)
{
    global $arr, $mod;
    $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
  
// Pre-compute factorials
cal_factorial();
  
$x = 3;
$y = 1;
print(getCount($x, $y));
  
// This code is contributed by chandan_jnu
?>

chevron_right


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.