📌  相关文章
📜  对于所有可能的长度为 M 的排序子序列,查找索引处所有元素的乘积,这些元素是 M 的因子

📅  最后修改于: 2021-09-03 04:03:20             🧑  作者: Mango

给定一个由N 个不同整数组成的数组arr[]和一个正整数M ,任务是找到索引处所有元素的乘积,这些元素是给定数组arr中长度为M的所有可能排序子序列的M的因子[] .
注:乘积可能很大,取模为10 9 + 7

例子:

方法:由于不可能找到所有的集合,想法是计算每个元素在所需位置出现的总次数。如果找到计数,则:

  • 为了找到 arr[i] 的计数,我们必须找到通过将 arr[i] 放在每个可能的索引(完全除 M)处可以形成的不同集合的总数。
  • 因此,将arr[i] 放在j(j 整除 m)索引形成的集合数将为:
  • 由于任何元素的计数可能非常大,因此为了找到(arr[i] count of arr[i] ) % (10 9 + 7) ,使用了费马小定理。

下面是上述方法的实现:

C++
// C++ program to find the product of
// all the combinations of M elements
// from an array whose index in the
// sorted order divides M completely
 
#include 
using namespace std;
 
typedef long long int lli;
const int m = 4;
 
// Iterative Function to calculate
// (x^y)%p in O(log y)
long long int power(lli x, lli y, lli p)
{
    lli res = 1;
    x = x % p;
 
    while (y > 0) {
 
        // If y is odd, multiply x with result
        if (y & 1)
            res = (res * x) % p;
 
        // y must be even now
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
 
// Iterative Function to calculate
// (nCr)%p and save in f[n][r]
// C(n, r)%p = [ C(n-1, r-1)%p + C(n-1, r)%p ] % p
// and C(n, 0) = C(n, n) = 1
void nCr(lli n, lli p, lli f[][m + 1])
{
    for (lli i = 0; i <= n; i++) {
        for (lli j = 0; j <= m; j++) {
 
            // If j>i then C(i, j) = 0
            if (j > i)
                f[i][j] = 0;
 
            // If i is equal to j then C(i, j) = 1
            else if (j == 0 || j == i)
                f[i][j] = 1;
 
            // C(i, j) = ( C(i-1, j) + C(i-1, j-1))%p
            else
                f[i][j] = (f[i - 1][j]
                           + f[i - 1][j - 1])
                          % p;
        }
    }
}
 
void operations(lli arr[], lli n, lli f[][m + 1])
{
    lli p = 1000000007;
    nCr(n, p - 1, f);
 
    sort(arr, arr + n);
 
    // Initialize the answer
    lli ans = 1;
 
    for (lli i = 0; i < n; i++) {
 
        // For every element arr[i],
        // x is count of occurrence
        // of arr[i] in different set
        // such that index of arr[i]
        // in those sets divides m completely.
        long long int x = 0;
 
        for (lli j = 1; j <= m; j++) {
 
            // Finding the count of arr[i]
            // by placing it at the index
            // which divides m completly
            if (m % j == 0)
 
                // Using fermat's little theorem
                x = (x
                     + (f[n - i - 1][m - j]
                        * f[i][j - 1])
                           % (p - 1))
                    % (p - 1);
        }
 
        // Multiplying with the count
        ans = ((ans * power(arr[i],
                            x, p))
               % p);
    }
 
    cout << ans << endl;
}
 
// Driver code
int main()
{
 
    lli arr[] = { 4, 5, 7, 9, 3 };
 
    lli n = sizeof(arr) / sizeof(arr[0]);
 
    lli f[n + 1][m + 1];
 
    operations(arr, n, f);
}


Java
// Java program to find the product of
// all the combinations of M elements
// from an array whose index in the
// sorted order divides M completely
import java.util.*;
 
class GFG{
 
static int m = 4;
 
// Iterative Function to calculate
// (x^y)%p in O(log y)
static long power(long x, long y, long p)
{
    long res = 1;
    x = x % p;
 
    while (y > 0)
    {
 
        // If y is odd, multiply
        // x with result
        if (y % 2 == 1)
            res = (res * x) % p;
 
        // y must be even now
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
 
// Iterative Function to calculate
// (nCr)%p and save in f[n][r]
// C(n, r)%p = [ C(n-1, r-1)%p + C(n-1, r)%p ] % p
// and C(n, 0) = C(n, n) = 1
static void nCr(int n, long p, int f[][])
{
    for(int i = 0; i <= n; i++)
    {
       for(int j = 0; j <= m; j++)
       {
           
          // If j>i then C(i, j) = 0
          if (j > i)
              f[i][j] = 0;
           
          // If i is equal to j
          // then C(i, j) = 1
          else if (j == 0 || j == i)
              f[i][j] = 1;
           
          // C(i, j) = ( C(i-1, j) + C(i-1, j-1))%p
          else
              f[i][j] = (f[i - 1][j] +
                         f[i - 1][j - 1]) % (int)p;
       }
    }
}
 
static void operations(int arr[], int n, int f[][])
{
    long p = 1000000007;
    nCr(n, p - 1, f);
 
    Arrays.sort(arr);
 
    // Initialize the answer
    long ans = 1;
 
    for(int i = 0; i < n; i++)
    {
        
       // For every element arr[i],
       // x is count of occurrence
       // of arr[i] in different set
       // such that index of arr[i]
       // in those sets divides m
       // completely.
       long x = 0;
        
       for(int j = 1; j <= m; j++)
       {
           
          // Finding the count of arr[i]
          // by placing it at the index
          // which divides m completly
          if (m % j == 0)
               
              // Using fermat's little theorem
              x = (x + (f[n - i - 1][m - j] *
                               f[i][j - 1]) %
                                   (p - 1)) %
                                   (p - 1);
       }
        
       // Multiplying with the count
       ans = ((ans * power(arr[i], x, p)) % p);
    }
    System.out.print(ans + "\n");
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 4, 5, 7, 9, 3 };
    int n = arr.length;
    int [][]f = new int[n + 1][m + 1];
 
    operations(arr, n, f);
}
}
 
// This code is contributed by Rohit_ranjan


Python3
# Python3 program to find the product of
# all the combinations of M elements
# from an array whose index in the
# sorted order divides M completely
m = 4
 
# Iterative Function to calculate
# (x^y)%p in O(log y)
def power(x, y, p):
 
    res = 1
    x = x % p
 
    while (y > 0):
 
        # If y is odd, multiply x with result
        if (y & 1):
            res = (res * x) % p
 
        # y must be even now
        y = y >> 1
        x = (x * x) % p
    return res
 
# Iterative Function to calculate
# (nCr)%p and save in f[n][r]
# C(n, r)%p = [ C(n-1, r-1)%p +
# C(n-1, r)%p ] % p
# and C(n, 0) = C(n, n) = 1
def nCr(n, p, f):
 
    for i in range (n):
        for j in range (m + 1):
 
            # If j>i then C(i, j) = 0
            if (j > i):
                f[i][j] = 0
 
            # If i is equal to j then
            # C(i, j) = 1
            elif (j == 0 or j == i):
                f[i][j] = 1
 
            # C(i, j) = ( C(i-1, j) +
            # C(i-1, j-1))%p
            else:
                f[i][j] = ((f[i - 1][j] +
                            f[i - 1][j - 1]) % p)
 
def operations(arr, n, f):
 
    p = 1000000007
    nCr(n, p - 1, f)
 
    arr.sort()
 
    # Initialize the answer
    ans = 1
     
    for i in range (n):
 
        # For every element arr[i],
        # x is count of occurrence
        # of arr[i] in different set
        # such that index of arr[i]
        # in those sets divides m completely.
        x = 0
 
        for j in range (1, m + 1):
 
            # Finding the count of arr[i]
            # by placing it at the index
            # which divides m completly
            if (m % j == 0):
 
                # Using fermat's little theorem
                x = ((x + (f[n - i - 1][m - j] *
                           f[i][j - 1]) % (p - 1)) %
                                          (p - 1))
        
        # Multiplying with the count
        ans = ((ans * power(arr[i],
                            x, p)) % p)
   
    print (ans)
 
# Driver code
if __name__ == "__main__":
    arr = [4, 5, 7, 9, 3]
    n = len(arr)
    f = [[0 for x in range (m + 1)]
            for y in range (n + 1)]
    operations(arr, n, f)
 
# This code is contributed by Chitranayal


C#
// C# program to find the product of
// all the combinations of M elements
// from an array whose index in the
// sorted order divides M completely
using System;
 
class GFG{
 
static int m = 4;
 
// Iterative Function to calculate
// (x^y)%p in O(log y)
static long power(long x, long y, long p)
{
    long res = 1;
    x = x % p;
 
    while (y > 0)
    {
 
        // If y is odd, multiply
        // x with result
        if (y % 2 == 1)
            res = (res * x) % p;
 
        // y must be even now
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
 
// Iterative Function to calculate
// (nCr)%p and save in f[n,r]
// C(n, r)%p = [ C(n-1, r-1)%p + C(n-1, r)%p ] % p
// and C(n, 0) = C(n, n) = 1
static void nCr(int n, long p, int [,]f)
{
    for(int i = 0; i <= n; i++)
    {
       for(int j = 0; j <= m; j++)
       {
           
          // If j>i then C(i, j) = 0
          if (j > i)
              f[i, j] = 0;
           
          // If i is equal to j
          // then C(i, j) = 1
          else if (j == 0 || j == i)
              f[i, j] = 1;
           
          // C(i, j) = ( C(i-1, j) + C(i-1, j-1))%p
          else
              f[i, j] = (f[i - 1, j] +
                         f[i - 1, j - 1]) % (int)p;
       }
    }
}
 
static void operations(int []arr, int n, int [,]f)
{
    long p = 1000000007;
    nCr(n, p - 1, f);
 
    Array.Sort(arr);
 
    // Initialize the answer
    long ans = 1;
 
    for(int i = 0; i < n; i++)
    {
        
       // For every element arr[i],
       // x is count of occurrence
       // of arr[i] in different set
       // such that index of arr[i]
       // in those sets divides m
       // completely.
       long x = 0;
       for(int j = 1; j <= m; j++)
       {
            
          // Finding the count of arr[i]
          // by placing it at the index
          // which divides m completly
          if (m % j == 0)
           
              // Using fermat's little theorem
              x = (x + (f[n - i - 1, m - j] *
                               f[i, j - 1]) %
                                   (p - 1)) %
                                   (p - 1);
       }
        
       // Multiplying with the count
       ans = ((ans * power(arr[i], x, p)) % p);
    }
    Console.Write(ans + "\n");
}
 
// Driver code
public static void Main(String[] args)
{
    int []arr = { 4, 5, 7, 9, 3 };
    int n = arr.Length;
    int [,]f = new int[n + 1, m + 1];
 
    operations(arr, n, f);
}
}
 
// This code is contributed by Rohit_ranjan


Javascript


输出:
808556639

时间复杂度: O(N * M) ,其中 N 是数组的长度,M 由用户指定。

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live