给定一个大小为N的数组arr[]和一个整数K 。任务是在所有可能的集合上找到f(S)的总和。对于有限集X , f(X)是max(X) – min(X) 。集合X包含给定数组中的任意K 个数字。输出可能非常大,因此,输出答案模10 9 +7 。
例子:
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
方法:假设arr预先排序,想法是通过预先计算直到N的阶乘及其逆来执行预计算以快速计算二项式系数。分别计算最小值和最大值的总和。换句话说, (∑ max(S)) – (∑ min(S))而不是∑ f(S) 。
为简单起见,假设arr i彼此不同。 max(S)的可能值是arr 的任何元素。因此,通过计数S的数量使得最大(S)=常用3我对于每个i,就可以找到最大Σ(S)。 max(S) = arr i 的充要条件是S包含arr i ,并且还包含小于arr i 的K-1 个元素,所以这个数可以直接用二项式系数计算。您可以类似地计算∑ minS 。
如果A i包含重复项,则可以证明如果假设arr之间的任意顺序具有相同的值,则上述解释也成立(例如,考虑 ( arr i , i的字典顺序并计算满足max( S) = (A i , i) . 因此,在这种情况下,您也可以按照相同的方式进行处理。
下面是上述方法的实现:
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[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
11
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live