Skip to content
Related Articles

Related Articles

Improve Article

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

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 <bits/stdc++.h>
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[0] = 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[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 
        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
Recommended Articles
Page :