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:
// 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 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 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# 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 |
// JS implementation of the approach let N = 100005 let mod = BigInt(1e9 + 7) // To store the factorial and the // factorial mod inverse of a number let factorial = new Array(N)
let modinverse = new Array(N);
// Function to find (a ^ m1) % mod function power(a, m1)
{ if (m1 == 0n)
return 1n;
else if (m1 == 1n)
return a;
else if (m1 == 2n)
return (a * a) % mod;
else if (m1 & 1n)
return (a
* power(power(a, m1 / 2n), 2n))
% mod;
else
return power(power(a, m1 / 2n), 2n) % mod;
} // Function to find factorial // of all the numbers function factorialfun()
{ factorial[0] = 1n;
for (let i = 1n; i < N; i++)
factorial[i] = (factorial[i - 1n] * i)
% mod;
} // Function to find the factorial // mod inverse of all the numbers function modinversefun()
{ modinverse[N - 1]
= power(factorial[N - 1], mod - 2n) % mod;
N = BigInt(N)
for ( var i = N - 2n; i >= 0n; i--)
modinverse[i] = (modinverse[i + 1n]
* (i + 1n))
% mod;
} // Function to return nCr function binomial(n, r)
{ if (r > n)
return 0n;
let 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 function max_min(a, n, k)
{ n = BigInt(n)
// Sort the given array
a.sort();
// Calculate the factorial and
// modinverse of all elements
factorialfun();
modinversefun();
let ans = 0n;
k--;
// For all the possible sets
// Calculate max(S) and min(S)
for ( var i = 0n; i < n; i++) {
var x = n - i - 1n;
if (x >= k)
ans -= binomial(x, k) * a[i] % mod;
var y = i;
if (y >= k)
ans += binomial(y, k) * a[i] % mod;
ans = (ans + mod) % mod;
}
return (ans);
} // Driver code let a= [ 1n, 1n, 3n, 4n ] let k = 2n; let n = a.length console.log(max_min(a, n, k)) // This code is contributed by phasing17 |
11