Open In App

Product of all sorted subsets of size K using elements whose index divide K completely

Given an integer array arr[] of N distinct elements and a positive integer K ( K <= N ). The task is to calculate the product of all sorted subsets of size K, from the given array, using elements whose index divide K completely.

Note: As the answer can be very large, print it modulo 10^9+7.



Examples: 

Input: arr[] = {4, 7, 5, 9, 3}, K = 4 
Output: 808556639 
Explanation: 
In this case there are 5 possible sets: 
{4, 7, 5, 9} -> 180 (Sorted order {4, 5, 7, 9}: Index 1, 2 and 4 divides M, so value of set is 4 * 5 * 9 = 180) 
{4, 7, 9, 3} -> 108 
{4, 5, 9, 3} -> 108 
{4, 7, 5, 3} -> 84 
{7, 5, 9, 3} -> 135 
Total value = ( 180 * 108 * 108 * 84 * 135 ) % (109+7) = 808556639



Input: arr[] = {7, 8, 9}, K = 2 
Output: 254016 
 

Naive Approach: 

We can find all the subsets of size K then sort the subsets and find the value of each subset and multiply it to get the final answer. 
As there can be 2N subsets, this approach will not be very efficient for a large value of N. 

Efficient Approach: 


 

( Total no. of elements smaller than arr[i] ) Cj-1 * ( Total no. of elements greater than arr[i] ) Ck-j 
 

{ a (p – 1) mod p = 1 } => { ( ax ) % p = ( a( x % p-1 )) % p }. 
 

So, by using Fermat’s little theorem
 

( arr[i] (count of arr[i] )) % ( 109 + 7 ) => ( arr[i] (count of arr[i] % 109 + 6 )) % ( 109 + 7 ). 
 

Below is the implementation of the above approach: 

// C++ implementation of the above approach
 
#include <bits/stdc++.h>
using namespace std;
int p = 1000000007;
 
// Iterative Function to calculate
// (x^y)%p in O(log y)
long long int power(long long int x,
                    long long int y,
                    long long int p)
{
    long long int 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]
void nCr(long long int n, long long int p,
         int f[][100], int m)
{
 
    for (long long int i = 0; i <= n; i++) {
        for (long long int j = 0; j <= m; j++) {
 
            // If j>i then C(i, j) = 0
            if (j > i) {
                f[i][j] = 0;
            }
 
            // If iis equal to j then
            // C(i, j) = 1
            else if (j == 0 || j == i) {
                f[i][j] = 1;
            }
 
            else {
                f[i][j] = (f[i - 1][j]
                           + f[i - 1][j - 1])
                          % p;
            }
        }
    }
}
 
// Function calculate the Final answer
void ProductOfSubsets(int arr[], int n,
                      int m)
{
    int f[n + 1][100];
 
    nCr(n, p - 1, f, m);
 
    sort(arr, arr + n);
 
    // Initialize ans
    long long int ans = 1;
 
    for (long long int i = 0; i < n; i++) {
 
        // x is count of occurrence of arr[i]
        // in different set such that index
        // of arr[i] in those sets divides
        // K completely.
        long long int x = 0;
 
        for (long long int j = 1; j <= m; j++) {
 
            // Finding the count of arr[i] by
            // placing it at index which
            // divides K completely
            if (m % j == 0) {
 
                // By Fermat's theorem
                x = (x
                     + (f[n - i - 1][m - j]
                        * f[i][j - 1])
                           % (p - 1))
                    % (p - 1);
            }
        }
 
        ans
            = ((ans * power(arr[i], x, p)) % p);
    }
 
    cout << ans << endl;
}
 
// Driver code
int main()
{
 
    int arr[] = { 4, 5, 7, 9, 3 };
    int K = 4;
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    ProductOfSubsets(arr, N, K);
 
    return 0;
}

                    
// Java implementation of the above approach
import java.util.*;
 
class GFG{
static int p = 1000000007;
 
// Iterative Function to calculate
// (x^y)%p in O(log y)
static int power(int x, int y, int p)
{
    int 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]
static void nCr(int n, int p,
                int f[][], int m)
{
    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 iis equal to j then
          // C(i, j) = 1
          else if (j == 0 || j == i)
          {
              f[i][j] = 1;
          }
          else
          {
              f[i][j] = (f[i - 1][j] +
                         f[i - 1][j - 1]) % p;
          }
       }
    }
}
 
// Function calculate the Final answer
static void ProductOfSubsets(int arr[], int n,
                                        int m)
{
    int [][]f = new int[n + 1][100];
 
    nCr(n, p - 1, f, m);
    Arrays.sort(arr);
 
    // Initialize ans
    long ans = 1;
 
    for(int i = 0; i < n; i++)
    {
         
       // x is count of occurrence of arr[i]
       // in different set such that index
       // of arr[i] in those sets divides
       // K completely.
       int x = 0;
        
       for(int j = 1; j <= m; j++)
       {
            
          // Finding the count of arr[i] by
          // placing it at index which
          // divides K completely
          if (m % j == 0)
          {
               
              // By Fermat's theorem
              x = (x + (f[n - i - 1][m - j] *
                        f[i][j - 1]) %
                        (p - 1)) %
                        (p - 1);
          }
       }
       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 K = 4;
    int N = arr.length;
 
    ProductOfSubsets(arr, N, K);
}
}
 
// This code is contributed by Rajput-Ji

                    
# Python3 implementation of the above approach
p = 1000000007
 
# 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]
def nCr(n, p, f, m):
     
    for i in range(n + 1):
        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
                 
            else:
                f[i][j] = (f[i - 1][j] +
                           f[i - 1][j - 1]) % p
 
# Function calculate the Final answer
def ProductOfSubsets(arr, n, m):
     
    f = [[0 for i in range(100)]
            for j in range(n + 1)]
 
    nCr(n, p - 1, f, m)
    arr.sort(reverse = False)
 
    # Initialize ans
    ans = 1
     
    for i in range(n):
         
        # x is count of occurrence of arr[i]
        # in different set such that index
        # of arr[i] in those sets divides
        # K completely.
        x = 0
 
        for j in range(1, m + 1, 1):
             
            # Finding the count of arr[i] by
            # placing it at index which
            # divides K completely
            if (m % j == 0):
                 
                # By Fermat's theorem
                x = ((x + (f[n - i - 1][m - j] *
                           f[i][j - 1]) %
                               (p - 1)) %
                               (p - 1))
 
        ans = ((ans * power(arr[i], x, p)) % p)
 
    print(ans)
 
# Driver code
if __name__ == '__main__':
     
    arr = [ 4, 5, 7, 9, 3 ]
    K = 4
    N = len(arr);
 
    ProductOfSubsets(arr, N, K)
 
# This code is contributed by samarth

                    
// C# implementation of the above approach
using System;
class GFG{
     
static int p = 1000000007;
 
// Iterative Function to calculate
// (x^y)%p in O(log y)
static int power(int x, int y, int p)
{
    int 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]
static void nCr(int n, int p,
                int [,]f, int m)
{
    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 iis equal to j then
            // C(i, j) = 1
            else if (j == 0 || j == i)
            {
                f[i, j] = 1;
            }
            else
            {
                f[i, j] = (f[i - 1, j] +
                           f[i - 1, j - 1]) % p;
            }
        }
    }
}
 
// Function calculate the Final answer
static void ProductOfSubsets(int []arr, int n,
                                        int m)
{
    int [,]f = new int[n + 1, 100];
 
    nCr(n, p - 1, f, m);
    Array.Sort(arr);
 
    // Initialize ans
    long ans = 1;
 
    for(int i = 0; i < n; i++)
    {
         
        // x is count of occurrence of arr[i]
        // in different set such that index
        // of arr[i] in those sets divides
        // K completely.
        int x = 0;
             
        for(int j = 1; j <= m; j++)
        {
                 
            // Finding the count of arr[i] by
            // placing it at index which
            // divides K completely
            if (m % j == 0)
            {
                     
                // By Fermat's theorem
                x = (x + (f[n - i - 1, m - j] *
                          f[i, j - 1]) %
                              (p - 1)) %
                              (p - 1);
            }
        }
        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 K = 4;
    int N = arr.Length;
 
    ProductOfSubsets(arr, N, K);
}
}
 
// This code is contributed by Rajput-Ji

                    
<script>
 
// Javascript implementation
// for the above approach
 
let p = 1000000007;
   
// Iterative Function to calculate
// (x^y)%p in O(log y)
function power(x, y, p)
{
    let 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]
function nCr(n, p, f, m)
{
    for(let i = 0; i <= n; i++)
    {
       for(let j = 0; j <= m; j++)
       {
              
          // If j>i then C(i, j) = 0
          if (j > i)
          {
              f[i][j] = 0;
          }
             
          // If iis equal to j then
          // C(i, j) = 1
          else if (j == 0 || j == i)
          {
              f[i][j] = 1;
          }
          else
          {
              f[i][j] = (f[i - 1][j] +
                         f[i - 1][j - 1]) % p;
          }
       }
    }
}
   
// Function calculate the Final answer
function ProductOfSubsets(arr, n, m)
{
    let f = new Array(n+1);
    for (var i = 0; i < f.length; i++) {
    f[i] = new Array(2);
    }
   
    nCr(n, p - 1, f, m);
    arr.sort();
   
    // Initialize ans
    let ans = 1;
   
    for(let i = 0; i < n; i++)
    {
           
       // x is count of occurrence of arr[i]
       // in different set such that index
       // of arr[i] in those sets divides
       // K completely.
       let x = 0;
          
       for(let j = 1; j <= m; j++)
       {
              
          // Finding the count of arr[i] by
          // placing it at index which
          // divides K completely
          if (m % j == 0)
          {
                 
              // By Fermat's theorem
              x = (x + (f[n - i - 1][m - j] *
                        f[i][j - 1]) %
                        (p - 1)) %
                        (p - 1);
          }
       }
       ans = ((ans * power(arr[i], x, p)) % p);
    }
    document.write(ans + "<br/>");
}
 
// Driver Code
     
    let arr = [ 4, 5, 7, 9, 3 ];
    let K = 4;
    let N = arr.length;
   
    ProductOfSubsets(arr, N, K);
       
</script>

                    

Output: 
808556639

 

Time Complexity: (N * K)

Auxiliary Space: O(N * 100)
 


Article Tags :