# 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

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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:

• The idea is not to create all the subsets to find the answer but to calculate the count of each element in all the subsets. If we find the count of each element in all subsets then the answer will be • For finding count of the arr[i], we have to find total number of the different subsets that can be formed by placing arr[i] at every possible index that divides K completely.
• Number of sets formed by placing arr[i] at jth index( j divides K completely) will be:

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

• As the count of any element may be very large, so for finding ( arr[i]( count of arr[i])) % ( 109 + 7 ) we have to use Fermat’s little theorem that is

{ 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++

 // C++ implementation of the above approach     #include  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[], 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];         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 occurence 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 completly              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);         ProductOfSubsets(arr, N, K);         return 0;  }

## Java

 // 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];         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 occurence 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 completly            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

 # 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 occurence 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 completly              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#

 // 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 occurence 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 completly              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

Output:

808556639


Time Complexity: (N * K)

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

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.

Improved By : ipg2016107, Rajput-Ji

Be the First to upvote.

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.