📌  相关文章
📜  从给定数组中找到所有选定集合的f(s)之和

📅  最后修改于: 2021-04-23 07:23:13             🧑  作者: Mango

给定大小为N的数组arr []和整数K。任务是在所有可能的集合中找到f(S)的总和。对于有限集Xf(X)max(X)– min(X) 。集X包含给定数组中的任何K个数字。输出可能非常大,因此,输出答案的模数为10 9 +7

例子:

方法:在假设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 ii的字典顺序,并计算满足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