📜  Bertrand投票定理的一个应用

📅  最后修改于: 2021-04-29 08:57:18             🧑  作者: Mango

鉴于其由集合{“X”,“Y”}字符的字符串“X”“Y”的数量,任务是找到满足条件排列的数量,其中的每个子串从第一个字符开始的置换具有count(’X’)> count(’Y’) 。打印答案模1000000007。请注意,在给定字符串, “ X”的数目将始终大于“ Y”的数目。

例子:

方法:这种类型的问题可以通过Bertrand的Ballot定理解决。在所有可能的分布中, X始终保留在线索中的概率为(X – Y)/(X + Y) 。分布总数为(X + Y)! /(X!* Y!) 。因此, X始终领先的分布为(X + Y – 1)! *(X – Y)/(X!* Y!)
用于计算(X + Y – 1)! *(X – Y)/(X!* Y!) ,我们需要计算X的乘法模逆因此,对于Y也是类似的。由于1000000007是素数,根据费马小定理: (1 / X!)%1000000007 =((X!) (1000000007 – 2) )%1000000007Y也有类似的结果。

下面是上述方法的实现:

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


输出:
2