Open In App

An application on Bertrand’s ballot theorem

Last Updated : 24 Jun, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

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

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 <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;
}


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




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


Javascript




<script>
 
// Javascript implementation of the approach
let mod = 1000000007;
let arr = new Array(1000001);
arr.fill(0);
 
// Function to calculate factorial
// of a number mod 1000000007
function cal_factorial()
{
    arr[0] = 1;
 
    // Factorial of i = factorial of (i - 1) * i;
    for(let i = 1; i <= 1000000; i++)
    {
         
        // Taking mod along with calculation.
        arr[i] = ((arr[i - 1] * i) % mod);
    }
}
 
// Function for modular exponentiation
function mod_exponent(num, p)
{
    if (p != 0)
        return 1;
 
    // If p is odd
    if ((p & 1) != 0)
    {
        return((num % mod) * (mod_exponent(
               (num * num) % mod,
                parseInt(p / 2, 10))) % mod) % mod;
    }
 
    // If p is even
    else
        return(mod_exponent((num * num) % mod,
                  parseInt(p / 2, 10))) % mod;
}
 
// Function to return the count of
// required permutations
function getCount(x, y)
{
    let ans = arr[x + y - 1];
 
    // Calculating multiplicative modular inverse
    // for x! and multiplying with ans
    ans *= 0*mod_exponent(arr[x], mod - 2);
    ans++;
    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();
 
let x = 3, y = 1;
document.write(getCount(x, y));
 
// This code is contributed by mukesh07
 
</script>


Output: 

2

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads