📌  相关文章
📜  除最小和最大元素外,所有大小为K的子序列的乘积

📅  最后修改于: 2021-04-24 04:45:33             🧑  作者: Mango

给定一个包含N个元素和整数K的数组A [] 。任务是计算大小为K的子序列的所有元素的乘积,每个子序列的最小和最大元素除外。

注意:由于答案可能非常大,因此将最终答案打印为mod 10 9 + 7

例子:

Input : arr[] = {1, 2, 3 4}, K = 3
Output : 36
Subsequences of length 3 are:
{1, 2, 3}, {1, 2, 4}, {1, 3, 4}, {2, 3, 4}
Excluding minimum and maximum elements from 
each of the above subsequences, product will be:
(2 * 2 * 3 * 3) = 36.

Input : arr[] = {10, 5, 16, 6}, k=3
Output : 3600

天真的方法:一种简单的方法是一一生成所有可能的子序列,然后将除最大和最小值之外的所有元素相乘,然后将所有元素进一步相乘。由于总共将有(n)个C (K)子序列,所有子序列都将相乘K – 2个元素,这是一件繁琐的工作。

高效方法:想法是首先对数组进行排序,因为考虑子序列或子集并不重要。

现在一一计算每个元素的出现。

总共有(n-1)个C (K-1)子序列出现,其中(i) C (K-1)次将作为最大元素出现,而(ni-1) C (K-1)次它将作为该子序列的最小元素出现。

因此,总计i_t_h元素将发生:

(n-1)C(K-1)  - (i)C(K-1) - (n-i-1)C(K-1) times. (let's say it x)

因此,首先,我们将为每个元素a [i]计算x,然后将a [i]乘以x倍。 IE ( a[i]^x mod(10^9 + 7) )。

由于,对于大型数组计算该值太困难了,因此我们将使用费马小定理。

下面是上述方法的实现:

C++
// C++ program to find product of all 
// Subsequences of size K except the 
// minimum and maximum Elements
  
#include 
using namespace std;
#define MOD 1000000007
  
#define ll long long
  
#define max 101
  
// 2D array to store value of 
// combinations nCr
ll C[max - 1][max - 1];
  
ll power(ll x, unsigned ll y)
{
    unsigned ll res = 1;
    x = x % MOD;
    while (y > 0) {
        if (y & 1) {
            res = (res * x) % MOD;
        }
  
        y = y >> 1;
        x = (x * x) % MOD;
    }
    return res % MOD;
}
  
// Function to pre-calculate value of all 
// combinations nCr
void combi(int n, int k)
{
    int i, j;
  
    for (i = 0; i <= n; i++) {
        for (j = 0; j <= min(i, k); j++) {
            if (j == 0 || j == i)
                C[i][j] = 1;
            else
                C[i][j] = (C[i - 1][j - 1] % MOD 
                            + C[i - 1][j] % MOD) % MOD;
        }
    }
}
  
// Function to calculate product of all subsequences 
// except the minimum and maximum elements
unsigned ll product(ll a[], int n, int k)
{
    unsigned ll ans = 1;
  
    // Sorting array so that it becomes easy 
    // to calculate the number of times an 
    // element will come in first or last place
    sort(a, a + n);
      
    // An element will occur 'powa' times in total
    // of which 'powla' times it will be last element
    // and 'powfa' times it will be first element
    ll powa = C[n - 1][k - 1];
  
    for (int i = 0; i < n; i++) {
        ll powla = C[i][k - 1];
        ll powfa = C[n - i - 1][k - 1];
          
        // In total it will come 
        // powe = powa-powla-powfa times
        ll powe = ((powa % MOD) - (powla + powfa) % MOD + MOD) % MOD;
          
        // Multiplying a[i] powe times using 
        // Fermat Little Theorem under MODulo 
        // MOD for fast exponentiation
        unsigned ll mul = power(a[i], powe) % MOD;
        ans = ((ans % MOD) * (mul % MOD)) % MOD;
    }
      
    return ans % MOD;
}
  
// Driver Code
int main()
{
    // pre-calculation of all combinations
    combi(100, 100);
  
    ll arr[] = { 1, 2, 3, 4 };
    int n = sizeof(arr) / sizeof arr[0];
    int k = 3;
  
    unsigned ll ans = product(arr, n, k);
      
    cout << ans << endl;
  
    return 0;
}


Java
// Java program to find product of all 
// Subsequences of size K except the 
// minimum and maximum Elements
import java.util.Arrays;
  
class GFG 
{
      
static int MOD= 1000000007;
static int max =101;
  
// 2D array to store value of 
// combinations nCr
static long C[][] = new long[max ][max];
  
static long power(long x, long y)
{
    long res = 1;
    x = x % MOD;
    while (y > 0)
    {
        if (y % 2== 1)
        {
            res = (res * x) % MOD;
        }
  
        y = y >> 1;
        x = (x * x) % MOD;
    }
    return res % MOD;
}
  
// Function to pre-calculate value of all 
// combinations nCr
static void combi(int n, int k)
{
    int i, j;
  
    for (i = 0; i <= n; i++)
    {
        for (j = 0; j <= Math.min(i, k); j++) 
        {
            if (j == 0 || j == i)
                C[i][j] = 1;
            else
                C[i][j] = (C[i - 1][j - 1] % MOD 
                            + C[i - 1][j] % MOD) % MOD;
        }
    }
}
  
// Function to calculate product of all subsequences 
// except the minimum and maximum elements
static long product(long a[], int n, int k)
{
    long ans = 1;
  
    // Sorting array so that it becomes easy 
    // to calculate the number of times an 
    // element will come in first or last place
    Arrays.sort(a);
      
    // An element will occur 'powa' times in total
    // of which 'powla' times it will be last element
    // and 'powfa' times it will be first element
    long powa = C[n - 1][k - 1];
  
    for (int i = 0; i < n; i++) 
    {
        long powla = C[i][k - 1];
        long powfa = C[n - i - 1][k - 1];
          
        // In total it will come 
        // powe = powa-powla-powfa times
        long powe = ((powa % MOD) - (powla + powfa) % MOD + MOD) % MOD;
          
        // Multiplying a[i] powe times using 
        // Fermat Little Theorem under MODulo 
        // MOD for fast exponentiation
        long mul = power(a[i], powe) % MOD;
        ans = ((ans % MOD) * (mul % MOD)) % MOD;
    }
      
    return ans % MOD;
}
  
// Driver Code
public static void main(String[] args)
{
    // pre-calculation of all combinations
    combi(100, 100);
  
    long arr[] = { 1, 2, 3, 4 };
    int n = arr.length;
    int k = 3;
  
    long ans = product(arr, n, k);
      
    System.out.println(ans);
}
}
  
/* This code contributed by PrinciRaj1992 */


Python3
# Python 3 program to find product of all 
# Subsequences of size K except the 
# minimum and maximum Elements
  
MOD = 1000000007
  
max = 101
  
# 2D array to store value of 
# combinations nCr
C = [[0 for i in range(max)] for j in range(max)]
  
def power(x,y):
    res = 1
    x = x % MOD
    while (y > 0):
        if (y & 1):
            res = (res * x) % MOD
  
        y = y >> 1
        x = (x * x) % MOD
  
    return res % MOD
  
# Function to pre-calculate value of all 
# combinations nCr
def combi(n, k):
    for i in range(n + 1):
        for j in range(min(i, k) + 1):
            if (j == 0 or j == i):
                C[i][j] = 1
            else:
                C[i][j] = (C[i - 1][j - 1] % MOD + 
                            C[i - 1][j] % MOD) % MOD
  
# Function to calculate product of all subsequences 
# except the minimum and maximum elements
def product(a, n, k):
    ans = 1
  
    # Sorting array so that it becomes easy 
    # to calculate the number of times an 
    # element will come in first or last place
    a.sort(reverse = False)
      
    # An element will occur 'powa' times in total
    # of which 'powla' times it will be last element
    # and 'powfa' times it will be first element
    powa = C[n - 1][k - 1]
  
    for i in range(n):
        powla = C[i][k - 1]
        powfa = C[n - i - 1][k - 1]
          
        # In total it will come 
        # powe = powa-powla-powfa times
        powe = ((powa % MOD) - (powla + powfa) % MOD + MOD) % MOD
          
        # Multiplying a[i] powe times using 
        # Fermat Little Theorem under MODulo 
        # MOD for fast exponentiation
        mul = power(a[i], powe) % MOD
        ans = ((ans % MOD) * (mul % MOD)) % MOD
      
    return ans % MOD
  
# Driver Code
if __name__ == '__main__':
    # pre-calculation of all combinations
    combi(100, 100)
  
    arr = [1, 2, 3, 4]
    n = len(arr)
    k = 3
  
    ans = product(arr, n, k)
    print(ans)
  
# This code is contributed by
# Surendra_Gangwar


C#
// C# program to find product of all 
// Subsequences of size K except the 
// minimum and maximum Elements
using System;
  
class GFG
{
static int MOD = 1000000007;
static int max = 101;
  
// 2D array to store value of 
// combinations nCr
static long [,]C = new long[max, max];
  
static long power(long x, long y)
{
    long res = 1;
    x = x % MOD;
    while (y > 0)
    {
        if (y % 2 == 1)
        {
            res = (res * x) % MOD;
        }
  
        y = y >> 1;
        x = (x * x) % MOD;
    }
    return res % MOD;
}
  
// Function to pre-calculate value 
// of all combinations nCr
static void combi(int n, int k)
{
    int i, j;
  
    for (i = 0; i <= n; i++)
    {
        for (j = 0;
             j <= Math.Min(i, k); j++) 
        {
            if (j == 0 || j == i)
                C[i, j] = 1;
            else
                C[i, j] = (C[i - 1, j - 1] % MOD + 
                           C[i - 1, j] % MOD) % MOD;
        }
    }
}
  
// Function to calculate product of 
// all subsequences except 
// the minimum and maximum elements
static long product(long []a, int n, int k)
{
    long ans = 1;
  
    // Sorting array so that it becomes easy 
    // to calculate the number of times an 
    // element will come in first or last place
    Array.Sort(a);
      
    // An element will occur 'powa' times 
    // in total of which 'powla' times it 
    // will be last element and 'powfa' times
    // it will be first element
    long powa = C[n - 1, k - 1];
  
    for (int i = 0; i < n; i++) 
    {
        long powla = C[i, k - 1];
        long powfa = C[n - i - 1, k - 1];
          
        // In total it will come 
        // powe = powa-powla-powfa times
        long powe = ((powa % MOD) -     
                     (powla + powfa) % 
                      MOD + MOD) % MOD;
          
        // Multiplying a[i] powe times using 
        // Fermat Little Theorem under MODulo 
        // MOD for fast exponentiation
        long mul = power(a[i], powe) % MOD;
        ans = ((ans % MOD) * 
               (mul % MOD)) % MOD;
    }
      
    return ans % MOD;
}
  
// Driver Code
static public void Main ()
{
    // pre-calculation of all combinations
    combi(100, 100);
  
    long []arr = { 1, 2, 3, 4 };
    int n = arr.Length;
    int k = 3;
  
    long ans = product(arr, n, k);
      
    Console.WriteLine(ans);
}
}
  
// This code contributed by ajit


输出:
36