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 = { 0 };    // Function to calculate factorial // of a number mod 1000000007 void cal_factorial() {     arr = 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;    // Function to calculate factorial // of a number mod 1000000007 static void cal_factorial() {     arr = 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 =  * (1000001)     # Function to calculate factorial # of a number mod 1000000007 def cal_factorial():        arr = 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;    // Function to calculate factorial // of a number mod 1000000007 static void cal_factorial() {     arr = 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.