Related Articles

# Find sum of f(s) for all the chosen sets from the given array

• Last Updated : 24 Apr, 2020

Given an array arr[] of size N and an integer K. The task is to find the sum of f(S) over all the possible sets. For a finite set X, f(X) is max(X) – min(X). Set X contains any K numbers from the given array. Output can be very large, so, output answer modulo 109+7.

Examples:

Input: arr[] = {1, 1, 3, 4}, K = 2
Output: 11
Sets are {1, 1}, {1, 3}, {1, 4}, {1, 3}, {1, 4}, {3, 4} and f(X) are 0, 2, 3, 2, 3, 1.

Input: arr[] = {10, -10, 10, -10, 10, -10}, K = 3
Output: 360
18 sets with f(X) equals to 20 and 2 sets with f(x) equals to 0

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

Approach: On assuming that arr is sorted beforehand, the idea is to perform precomputation to calculate binomial coefficients fast by precalculating the factorials till N and their inverses. The sum is calculated separately for min and max. In other words, (∑ max(S)) – (∑ min(S)) instead of ∑ f(S).
For simplicity, assume that arri is distinct from each other. The possible value of max(S) is any element of arr. Therefore, by counting the number of S such that max(S) = arri for each i, you can find ∑ max(S). The necessary and sufficient condition of max(S) = arri is S contains arri, and also contains K-1 elements less than arri, so such number can be directly calculated by using binomial coefficients. You can calculate ∑ minS similarly.
If Ai contains duplicates, you can prove that the explanation above also holds if you assume arbitrary order between arr is with the same value (for example, consider a lexicographical order of(arri, i and count the number of elements satisfying max(S) = (Ai, i). Therefore, you can also process in the same way in this case.

Below is the implementation of the above approach:

## CPP

 `// C++ implementation of the approach``#include ``using` `namespace` `std;``#define N 100005``#define mod (int)(1e9 + 7)`` ` `// To store the factorial and the``// factorial mod inverse of a number``int` `factorial[N], modinverse[N];`` ` `// Function to find (a ^ m1) % mod``int` `power(``int` `a, ``int` `m1)``{``    ``if` `(m1 == 0)``        ``return` `1;``    ``else` `if` `(m1 == 1)``        ``return` `a;``    ``else` `if` `(m1 == 2)``        ``return` `(1LL * a * a) % mod;``    ``else` `if` `(m1 & 1)``        ``return` `(1LL * a``                ``* power(power(a, m1 / 2), 2))``               ``% mod;``    ``else``        ``return` `power(power(a, m1 / 2), 2) % mod;``}`` ` `// Function to find factorial``// of all the numbers``void` `factorialfun()``{``    ``factorial = 1;``    ``for` `(``int` `i = 1; i < N; i++)``        ``factorial[i] = (1LL``                        ``* factorial[i - 1] * i)``                       ``% mod;``}`` ` `// Function to find the factorial``// mod inverse of all the numbers``void` `modinversefun()``{``    ``modinverse[N - 1]``        ``= power(factorial[N - 1], mod - 2) % mod;`` ` `    ``for` `(``int` `i = N - 2; i >= 0; i--)``        ``modinverse[i] = (1LL * modinverse[i + 1]``                         ``* (i + 1))``                        ``% mod;``}`` ` `// Function to return nCr``int` `binomial(``int` `n, ``int` `r)``{``    ``if` `(r > n)``        ``return` `0;`` ` `    ``int` `a = (1LL * factorial[n]``             ``* modinverse[n - r])``            ``% mod;`` ` `    ``a = (1LL * a * modinverse[r]) % mod;``    ``return` `a;``}`` ` `// Function to find sum of f(s) for all``// the chosen sets from the given array``int` `max_min(``int` `a[], ``int` `n, ``int` `k)``{``    ``// Sort the given array``    ``sort(a, a + n);`` ` `    ``// Calculate the factorial and``    ``// modinverse of all elements``    ``factorialfun();``    ``modinversefun();`` ` `    ``long` `long` `ans = 0;``    ``k--;`` ` `    ``// For all the possible sets``    ``// Calculate max(S) and min(S)``    ``for` `(``int` `i = 0; i < n; i++) {``        ``int` `x = n - i - 1;``        ``if` `(x >= k)``            ``ans -= binomial(x, k) * a[i] % mod;`` ` `        ``int` `y = i;``        ``if` `(y >= k)``            ``ans += binomial(y, k) * a[i] % mod;`` ` `        ``ans = (ans + mod) % mod;``    ``}`` ` `    ``return` `(``int``)(ans);``}`` ` `// Driver code``int` `main()``{``    ``int` `a[] = { 1, 1, 3, 4 }, k = 2;``    ``int` `n = ``sizeof``(a) / ``sizeof``(``int``);`` ` `    ``cout << max_min(a, n, k);`` ` `    ``return` `0;``}`

## Java

 `// Java implementation of the approach``import` `java.util.*;`` ` `class` `GFG{`` ` `static` `int` `N = ``100005``;``static` `int` `mod = ``1000000007``;``static` `int` `temp = ``391657242``;`` ` `// To store the factorial and the``// factorial mod inverse of a number``static` `int` `[]factorial = ``new` `int``[N];``static` `int` `[]modinverse = ``new` `int``[N];`` ` `// Function to find (a ^ m1) % mod``static` `int` `power(``int` `a, ``int` `m1)``{``    ``if` `(m1 == ``0``)``        ``return` `1``;``    ``else` `if` `(m1 == ``1``)``        ``return` `a;``    ``else` `if` `(m1 == ``2``)``        ``return` `(a * a) % mod;``    ``else` `if` `((m1 & ``1``)!=``0``)``        ``return` `(a * power(power(a, m1 / ``2``), ``2``)) % mod;``    ``else``        ``return` `power(power(a, m1 / ``2``), ``2``) % mod;``}`` ` `// Function to find factorial``// of all the numbers``static` `void` `factorialfun()``{``    ``factorial[``0``] = ``1``;``    ``for` `(``int` `i = ``1``; i < N; i++)``        ``factorial[i] = (factorial[i - ``1``] * i)% mod;``}`` ` `// Function to find the factorial``// mod inverse of all the numbers``static` `void` `modinversefun()``{``    ``modinverse[N - ``1``] = power(factorial[N - ``1``], mod - ``2``) % mod;`` ` `    ``for` `(``int` `i = N - ``2``; i >= ``0``; i--)``        ``modinverse[i] = (modinverse[i + ``1``]*(i + ``1``))%mod;``}`` ` `// Function to return nCr``static` `int` `binomial(``int` `n, ``int` `r)``{``    ``if` `(r > n)``        ``return` `0``;`` ` `    ``int` `a = (factorial[n] * modinverse[n - r]) % mod;`` ` `    ``a = (a * modinverse[r]) % mod;``    ``return` `a;``}`` ` `// Function to find sum of f(s) for all``// the chosen sets from the given array``static` `int` `max_min(``int` `a[], ``int` `n, ``int` `k)``{``    ``// Sort the given array``    ``Arrays.sort(a);`` ` `    ``// Calculate the factorial and``    ``// modinverse of all elements``    ``factorialfun();``    ``modinversefun();`` ` `    ``int` `ans = ``0``;``    ``k--;`` ` `    ``// For all the possible sets``    ``// Calculate max(S) and min(S)``    ``for` `(``int` `i = ``0``; i < n; i++) {``        ``int` `x = n - i - ``1``;``        ``if` `(x >= k)``            ``ans -= binomial(x, k) * a[i] % mod;`` ` `        ``int` `y = i;``        ``if` `(y >= k)``            ``ans += binomial(y, k) * a[i] % mod;`` ` `        ``ans = (ans + mod) % mod;``    ``}`` ` `    ``return` `ans%temp;``}`` ` `// Driver code``public` `static` `void` `main(String args[])``{``    ``int` `[]a = { ``1``, ``1``, ``3``, ``4` `};``    ``int` `k = ``2``;``    ``int` `n = a.length;`` ` `    ``System.out.println(max_min(a, n, k));``}``}`` ` `// This code is contributed by Surendra_Gangwar`

## Python3

 `# Python3 implementation of the approach``N ``=` `100005``mod ``=` `(``10` `*``*` `9` `+` `7``)`` ` `# To store the factorial and the``# factorial mod inverse of a number``factorial ``=` `[``0``]``*``N``modinverse ``=` `[``0``]``*``N`` ` `# Function to find factorial``# of all the numbers``def` `factorialfun():``    ``factorial[``0``] ``=` `1``    ``for` `i ``in` `range``(``1``, N):``        ``factorial[i] ``=` `(factorial[i ``-` `1``] ``*` `i)``%``mod`` ` `# Function to find the factorial``# mod inverse of all the numbers``def` `modinversefun():``    ``modinverse[N ``-` `1``] ``=` `pow``(factorial[N ``-` `1``], ``                            ``mod ``-` `2``, mod) ``%` `mod`` ` `    ``for` `i ``in` `range``(N ``-` `2``, ``-``1``, ``-``1``):``        ``modinverse[i] ``=` `(modinverse[i ``+` `1``]``*` `(i ``+` `1``))``%` `mod`` ` `# Function to return nCr``def` `binomial(n, r):``    ``if` `(r > n):``        ``return` `0`` ` `    ``a ``=` `(factorial[n]``*` `modinverse[n ``-` `r])``%` `mod`` ` `    ``a ``=` `(a ``*` `modinverse[r]) ``%` `mod``    ``return` `a`` ` `# Function to find sum of f(s) for all``# the chosen sets from the given array``def` `max_min(a, n, k):`` ` `    ``# Sort the given array``    ``a ``=` `sorted``(a)`` ` `    ``# Calculate the factorial and``    ``# modinverse of all elements``    ``factorialfun()``    ``modinversefun()`` ` `    ``ans ``=` `0``    ``k ``-``=` `1`` ` `    ``# For all the possible sets``    ``# Calculate max(S) and min(S)``    ``for` `i ``in` `range``(n):``        ``x ``=` `n ``-` `i ``-` `1``        ``if` `(x >``=` `k):``            ``ans ``-``=` `(binomial(x, k) ``*` `a[i]) ``%` `mod`` ` `        ``y ``=` `i``        ``if` `(y >``=` `k):``            ``ans ``+``=` `(binomial(y, k) ``*` `a[i]) ``%` `mod`` ` `        ``ans ``=` `(ans ``+` `mod) ``%` `mod`` ` `    ``return` `ans`` ` `# Driver code`` ` `a ``=` `[``1``, ``1``, ``3``, ``4``]``k ``=` `2``n ``=` `len``(a)`` ` `print``(max_min(a, n, k))`` ` `# This code is contributed by mohit kumar 29`

## C#

 `// C# implementation of the approach ``using` `System;``     ` `class` `GFG{ ``     ` `    ``static` `int` `N = 100005; ``    ``static` `int` `mod = 1000000007; ``    ``static` `int` `temp = 391657242; ``     ` `    ``// To store the factorial and the ``    ``// factorial mod inverse of a number ``    ``static` `int` `[]factorial = ``new` `int``[N]; ``    ``static` `int` `[]modinverse = ``new` `int``[N]; ``     ` `    ``// Function to find (a ^ m1) % mod ``    ``static` `int` `power(``int` `a, ``int` `m1) ``    ``{ ``        ``if` `(m1 == 0) ``            ``return` `1; ``        ``else` `if` `(m1 == 1) ``            ``return` `a; ``        ``else` `if` `(m1 == 2) ``            ``return` `(a * a) % mod; ``        ``else` `if` `((m1 & 1)!=0) ``            ``return` `(a * power(power(a, m1 / 2), 2)) % mod; ``        ``else``            ``return` `power(power(a, m1 / 2), 2) % mod; ``    ``} ``     ` `    ``// Function to find factorial ``    ``// of all the numbers ``    ``static` `void` `factorialfun() ``    ``{ ``        ``factorial = 1; ``        ``for` `(``int` `i = 1; i < N; i++) ``            ``factorial[i] = (factorial[i - 1] * i)% mod; ``    ``} ``     ` `    ``// Function to find the factorial ``    ``// mod inverse of all the numbers ``    ``static` `void` `modinversefun() ``    ``{ ``        ``modinverse[N - 1] = power(factorial[N - 1], mod - 2) % mod; ``     ` `        ``for` `(``int` `i = N - 2; i >= 0; i--) ``            ``modinverse[i] = (modinverse[i + 1]*(i + 1)) % mod; ``    ``} ``     ` `    ``// Function to return nCr ``    ``static` `int` `binomial(``int` `n, ``int` `r) ``    ``{ ``        ``if` `(r > n) ``            ``return` `0; ``     ` `        ``int` `a = (factorial[n] * modinverse[n - r]) % mod; ``     ` `        ``a = (a * modinverse[r]) % mod; ``        ``return` `a; ``    ``} ``     ` `    ``// Function to find sum of f(s) for all ``    ``// the chosen sets from the given array ``    ``static` `int` `max_min(``int` `[]a, ``int` `n, ``int` `k) ``    ``{ ``        ``// Sort the given array ``        ``Array.Sort(a); ``     ` `        ``// Calculate the factorial and ``        ``// modinverse of all elements ``        ``factorialfun(); ``        ``modinversefun(); ``     ` `        ``int` `ans = 0; ``        ``k--; ``     ` `        ``// For all the possible sets ``        ``// Calculate max(S) and min(S) ``        ``for` `(``int` `i = 0; i < n; i++) { ``            ``int` `x = n - i - 1; ``            ``if` `(x >= k) ``                ``ans -= binomial(x, k) * a[i] % mod; ``     ` `            ``int` `y = i; ``            ``if` `(y >= k) ``                ``ans += binomial(y, k) * a[i] % mod; ``     ` `            ``ans = (ans + mod) % mod; ``        ``} ``     ` `        ``return` `ans % temp; ``    ``} ``     ` `    ``// Driver code ``    ``public` `static` `void` `Main(``string` `[]args) ``    ``{ ``        ``int` `[]a = { 1, 1, 3, 4 }; ``        ``int` `k = 2; ``        ``int` `n = a.Length; ``     ` `        ``Console.WriteLine(max_min(a, n, k)); ``    ``} ``} `` ` `// This code is contributed by AnkitRai01`
Output:
```11
```

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up