📌  相关文章
📜  计算中位数也出现在同一子集中的子集的数量

📅  最后修改于: 2021-04-22 02:28:10             🧑  作者: Mango

给定大小为N的数组arr [] ,任务是计算我们可以从给定数组元素中选择一个子集的方式的数量,以使所选子集的中位数也作为子集中的元素出现。由于此数字可能很大,因此请对1000000007取模。

例子:

方法:

  • 每个奇数大小的子集在子集中都有其中位数,因此,我们可以直接在答案中加上2 N – 1
  • 对于偶数大小的子集,当且仅当中间两个元素相等时,才会选择该子集。
  • 我们需要计算中间元素相等的大小相等的子集的数量。

简单的解决方案是迭代每对相等的元素(i,j),使得A [i] = A [j]并遍历子集的大小2 * X从X = 1到N。用两个固定的中间元素来制作大小为X的子集,这只是我们从[1,i – 1]中选择X – 1个元素和从[j + 1,N]中选择X – 1个元素的方式数量的乘积。

该解决方案需要遍历每对(i,j),这花费O(N 2 )时间和每对O(N)时间,从而导致总体时间复杂度O(N 3 )

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
#include 
using namespace std;
long long mod = 1000000007;
  
// Function to return the factorial of a number
int fact(int n)
{
    int res = 1;
    for (int i = 2; i <= n; i++)
        res = res * i;
    return res;
}
  
// Function to return the value of nCr
int nCr(int n, int r)
{
    return fact(n) / (fact(r) * fact(n - r));
}
  
// Function to return a raised to the power n
// with complexity O(log(n))
long long powmod(long long a, long long n)
{
    if (!n)
        return 1;
    long long pt = powmod(a, n / 2);
    pt = (pt * pt) % mod;
    if (n % 2)
        return (pt * a) % mod;
    else
        return pt;
}
  
// Function to return the number of sub-sets
// whose median is also present in the set
long long CountSubset(int* arr, int n)
{
  
    // Number of odd length sub-sets
    long long ans = powmod(2, n - 1);
  
    // Sort the array
    sort(arr, arr + n);
    for (int i = 0; i < n; ++i) {
        int j = i + 1;
  
        // Checking each element for leftmost middle
        // element while they are equal
        while (j < n && arr[j] == arr[i]) {
  
            // Calculate the number of elements in
            // right of rightmost middle element
            int r = n - 1 - j;
  
            // Calculate the number of elements in
            // left of leftmost middle element
            int l = i;
  
            // Add selected even length subsets
            // to the answer
            ans = (ans + nCr(l + r, l)) % mod;
            j++;
        }
    }
  
    return ans;
}
  
// Driver code
int main()
{
    int arr[] = { 2, 3, 2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << CountSubset(arr, n) << endl;
  
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
  
class GFG {
  
    static long mod = 1000000007;
  
    // Function to return the factorial of a number
    static int fact(int n)
    {
        int res = 1;
        for (int i = 2; i <= n; i++)
            res = res * i;
        return res;
    }
  
    // Function to return the value of nCr
    static int nCr(int n, int r)
    {
        return fact(n) / (fact(r) * fact(n - r));
    }
  
    // Function to return a raised to the power n
    // with complexity O(log(n))
    static long powmod(long a, long n)
    {
        if (n == 0)
            return 1;
        long pt = powmod(a, n / 2);
        pt = (pt * pt) % mod;
        if (n % 2 == 1)
            return (pt * a) % mod;
        else
            return pt;
    }
  
    // Function to return the number of sub-sets
    // whose median is also present in the set
    static long CountSubset(int[] arr, int n)
    {
  
        // Number of odd length sub-sets
        long ans = powmod(2, n - 1);
  
        // Sort the array
        Arrays.sort(arr);
        for (int i = 0; i < n; ++i) {
            int j = i + 1;
  
            // Checking each element for leftmost middle
            // element while they are equal
            while (j < n && arr[j] == arr[i]) {
  
                // Calculate the number of elements in
                // right of rightmost middle element
                int r = n - 1 - j;
  
                // Calculate the number of elements in
                // left of leftmost middle element
                int l = i;
  
                // Add selected even length subsets
                // to the answer
                ans = (ans + nCr(l + r, l)) % mod;
                j++;
            }
        }
  
        return ans;
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 2, 3, 2 };
        int n = arr.length;
        System.out.println(CountSubset(arr, n));
    }
}
  
// This code has been contributed by 29AjayKumar


Python3
# Python 3 implementation of the approach
mod = 1000000007
  
# Function to return 
# the factorial of a number
def fact(n):
    res = 1
    for i in range(2, n + 1):
        res = res * i
    return res
  
# Function to return the value of nCr
def nCr(n, r):
    return int(fact(n) / (fact(r) * 
                          fact(n - r)))
  
# Function to return 'a' raised to the power n
# with complexity O(log(n))
def powmod(a, n):
    if (n == 0):
        return 1
    pt = powmod(a, int(n / 2))
    pt = (pt * pt) % mod
    if (n % 2):
        return (pt * a) % mod
    else:
        return pt
  
# Function to return the number of sub-sets
# whose median is also present in the set
def CountSubset(arr, n):
      
    # Number of odd length sub-sets
    ans = powmod(2, n - 1)
  
    # Sort the array
    arr.sort(reverse = False)
    for i in range(n):
        j = i + 1
  
        # Checking each element for leftmost middle
        # element while they are equal
        while (j < n and arr[j] == arr[i]):
              
            # Calculate the number of elements in
            # right of rightmost middle element
            r = n - 1 - j
  
            # Calculate the number of elements in
            # left of leftmost middle element
            l = i
  
            # Add selected even length subsets
            # to the answer
            ans = (ans + nCr(l + r, l)) % mod
            j += 1
  
    return ans
  
# Driver code
if __name__ == '__main__':
    arr = [2, 3, 2]
    n = len(arr)
    print(CountSubset(arr, n))
  
# This code is contributed by
# Surendra_Gangwar


C#
// C# implementation of the approach
using System;
  
class GFG {
  
    static long mod = 1000000007;
  
    // Function to return the factorial of a number
    static int fact(int n)
    {
        int res = 1;
        for (int i = 2; i <= n; i++)
            res = res * i;
        return res;
    }
  
    // Function to return the value of nCr
    static int nCr(int n, int r)
    {
        return fact(n) / (fact(r) * fact(n - r));
    }
  
    // Function to return a raised to the power n
    // with complexity O(log(n))
    static long powmod(long a, long n)
    {
        if (n == 0)
            return 1;
        long pt = powmod(a, n / 2);
        pt = (pt * pt) % mod;
        if (n % 2 == 1)
            return (pt * a) % mod;
        else
            return pt;
    }
  
    // Function to return the number of sub-sets
    // whose median is also present in the set
    static long CountSubset(int[] arr, int n)
    {
  
        // Number of odd length sub-sets
        long ans = powmod(2, n - 1);
  
        // Sort the array
        Array.Sort(arr);
        for (int i = 0; i < n; ++i) {
            int j = i + 1;
  
            // Checking each element for leftmost middle
            // element while they are equal
            while (j < n && arr[j] == arr[i]) {
  
                // Calculate the number of elements in
                // right of rightmost middle element
                int r = n - 1 - j;
  
                // Calculate the number of elements in
                // left of leftmost middle element
                int l = i;
  
                // Add selected even length subsets
                // to the answer
                ans = (ans + nCr(l + r, l)) % mod;
                j++;
            }
        }
  
        return ans;
    }
  
    // Driver code
    public static void Main(String[] args)
    {
        int[] arr = { 2, 3, 2 };
        int n = arr.Length;
        Console.WriteLine(CountSubset(arr, n));
    }
}
  
// This code has been contributed by 29AjayKumar


PHP


C++
// C++ implementation of the approach
#include 
#include 
using namespace std;
long long mod = 1000000007;
long long arr[1001][1001];
  
// Function to store pascal triangle in 2-d array
void Preprocess()
{
    arr[0][0] = 1;
    for (int i = 1; i <= 1000; ++i) {
        arr[i][0] = 1;
        for (int j = 1; j < i; ++j) {
            arr[i][j] = (arr[i - 1][j - 1] + arr[i - 1][j]) % mod;
        }
        arr[i][i] = 1;
    }
}
  
// Function to return a raised to the power n
// with complexity O(log(n))
long long powmod(long long a, long long n)
{
    if (!n)
        return 1;
    long long pt = powmod(a, n / 2);
    pt = (pt * pt) % mod;
    if (n % 2)
        return (pt * a) % mod;
    else
        return pt;
}
  
// Function to return the number of sub-sets
// whose median is also present in the set
long long CountSubset(int* val, int n)
{
  
    // Number of odd length sub-sets
    long long ans = powmod(2, n - 1);
  
    // Sort the array
    sort(val, val + n);
    for (int i = 0; i < n; ++i) {
        int j = i + 1;
  
        // Checking each element for leftmost middle
        // element while they are equal
        while (j < n && val[j] == val[i]) {
  
            // Calculate the number of elements in
            // right of rightmost middle element
            int r = n - 1 - j;
  
            // Calculate the number of elements in
            // left of leftmost middle element
            int l = i;
  
            // Add selected even length subsets
            // to the answer
            ans = (ans + arr[l + r][l]) % mod;
            j++;
        }
    }
  
    return ans;
}
  
// Driver code
int main()
{
    Preprocess();
    int val[] = { 2, 3, 2 };
    int n = sizeof(val) / sizeof(val[0]);
    cout << CountSubset(val, n) << endl;
  
    return 0;
}


Java
// Java implementation of the above approach
import java.util.Arrays;
  
class GFG 
{
  
    static long mod = 1000000007;
    static long[][] arr = new long[1001][1001];
  
    // Function to store pascal triangle in 2-d array 
    static void Preprocess() 
    {
        arr[0][0] = 1;
        for (int i = 1; i <= 1000; ++i)
        {
            arr[i][0] = 1;
            for (int j = 1; j < i; ++j) 
            {
                arr[i][j] = (arr[i - 1][j - 1] + arr[i - 1][j]) % mod;
            }
            arr[i][i] = 1;
        }
    }
  
    // Function to return a raised to the power n 
    // with complexity O(log(n)) 
    static long powmod(long a, long n) 
    {
        if (n == 0)
        {
            return 1;
        }
        long pt = powmod(a, n / 2);
        pt = (pt * pt) % mod;
        if (n % 2 == 1) 
        {
            return (pt * a) % mod;
        } 
        else
        {
            return pt;
        }
    }
  
    // Function to return the number of sub-sets 
    // whose median is also present in the set 
    static long CountSubset(int[] val, int n)
    {
  
        // Number of odd length sub-sets 
        long ans = powmod(2, n - 1);
  
        // Sort the array 
        Arrays.sort(val);
        for (int i = 0; i < n; ++i) 
        {
            int j = i + 1;
  
            // Checking each element for leftmost middle 
            // element while they are equal 
            while (j < n && val[j] == val[i])
            {
  
                // Calculate the number of elements in 
                // right of rightmost middle element 
                int r = n - 1 - j;
  
                // Calculate the number of elements in 
                // left of leftmost middle element 
                int l = i;
  
                // Add selected even length subsets 
                // to the answer 
                ans = (ans + arr[l + r][l]) % mod;
                j++;
            }
        }
  
        return ans;
    }
  
    // Driver code 
    public static void main(String[] args)
    {
        Preprocess();
        int val[] = {2, 3, 2};
        int n = val.length;
  
        System.out.println(CountSubset(val, n));
    }
}
  
// This code contributed by Rajput-Ji


Python3
# Python3 implementation of the approach 
mod = 1000000007 
arr = [[None for i in range(1001)] for j in range(1001)] 
  
# Function to store pascal triangle in 2-d array 
def Preprocess(): 
   
    arr[0][0] = 1 
    for i in range(1, 1001):  
        arr[i][0] = 1 
        for j in range(1, i):  
            arr[i][j] = (arr[i - 1][j - 1] + arr[i - 1][j]) % mod 
           
        arr[i][i] = 1 
       
# Function to return a raised to the power n 
# with complexity O(log(n)) 
def powmod(a, n): 
   
    if not n: 
        return 1 
    pt = powmod(a, n // 2) 
    pt = (pt * pt) % mod 
    if n % 2: 
        return (pt * a) % mod 
    else:
        return pt 
  
# Function to return the number of sub-sets 
# whose median is also present in the set 
def CountSubset(val, n): 
   
    # Number of odd length sub-sets 
    ans = powmod(2, n - 1) 
  
    # Sort the array 
    val.sort() 
    for i in range(0, n):  
        j = i + 1 
  
        # Checking each element for leftmost middle 
        # element while they are equal 
        while j < n and val[j] == val[i]:  
  
            # Calculate the number of elements in 
            # right of rightmost middle element 
            r = n - 1 - j 
  
            # Calculate the number of elements in 
            # left of leftmost middle element 
            l = i 
  
            # Add selected even length 
            # subsets to the answer 
            ans = (ans + arr[l + r][l]) % mod 
            j += 1
  
    return ans 
   
# Driver code 
if __name__ == "__main__": 
   
    Preprocess() 
    val = [2, 3, 2]
    n = len(val) 
    print(CountSubset(val, n))
  
# This code is contributed by Rituraj Jain


C#
// C# implementation of the above approach
using System;
      
class GFG 
{
  
    static long mod = 1000000007;
    static long [,]arr = new long[1001,1001];
  
    // Function to store pascal triangle in 2-d array 
    static void Preprocess() 
    {
        arr[0,0] = 1;
        for (int i = 1; i <= 1000; ++i)
        {
            arr[i,0] = 1;
            for (int j = 1; j < i; ++j) 
            {
                arr[i,j] = (arr[i - 1,j - 1] + arr[i - 1,j]) % mod;
            }
            arr[i,i] = 1;
        }
    }
  
    // Function to return a raised to the power n 
    // with complexity O(log(n)) 
    static long powmod(long a, long n) 
    {
        if (n == 0)
        {
            return 1;
        }
        long pt = powmod(a, n / 2);
        pt = (pt * pt) % mod;
        if (n % 2 == 1) 
        {
            return (pt * a) % mod;
        } 
        else
        {
            return pt;
        }
    }
  
    // Function to return the number of sub-sets 
    // whose median is also present in the set 
    static long CountSubset(int[] val, int n)
    {
  
        // Number of odd length sub-sets 
        long ans = powmod(2, n - 1);
  
        // Sort the array 
        Array.Sort(val);
        for (int i = 0; i < n; ++i) 
        {
            int j = i + 1;
  
            // Checking each element for leftmost middle 
            // element while they are equal 
            while (j < n && val[j] == val[i])
            {
  
                // Calculate the number of elements in 
                // right of rightmost middle element 
                int r = n - 1 - j;
  
                // Calculate the number of elements in 
                // left of leftmost middle element 
                int l = i;
  
                // Add selected even length subsets 
                // to the answer 
                ans = (ans + arr[l + r,l]) % mod;
                j++;
            }
        }
  
        return ans;
    }
  
    // Driver code 
    public static void Main(String[] args)
    {
        Preprocess();
        int []val = {2, 3, 2};
        int n = val.Length;
  
        Console.WriteLine(CountSubset(val, n));
    }
}
  
/* This code contributed by PrinciRaj1992 */


输出:
5

时间复杂度: O(N 3 )

如果将帕斯卡三角形存储在二维数组中,则上述方法的时间复杂度可以降低为O(N 2 )。因此,现在我们不必一次又一次地计算阶乘。在此处阅读有关Pascal三角形的更多信息。

下面是上述方法的实现:

C++

// C++ implementation of the approach
#include 
#include 
using namespace std;
long long mod = 1000000007;
long long arr[1001][1001];
  
// Function to store pascal triangle in 2-d array
void Preprocess()
{
    arr[0][0] = 1;
    for (int i = 1; i <= 1000; ++i) {
        arr[i][0] = 1;
        for (int j = 1; j < i; ++j) {
            arr[i][j] = (arr[i - 1][j - 1] + arr[i - 1][j]) % mod;
        }
        arr[i][i] = 1;
    }
}
  
// Function to return a raised to the power n
// with complexity O(log(n))
long long powmod(long long a, long long n)
{
    if (!n)
        return 1;
    long long pt = powmod(a, n / 2);
    pt = (pt * pt) % mod;
    if (n % 2)
        return (pt * a) % mod;
    else
        return pt;
}
  
// Function to return the number of sub-sets
// whose median is also present in the set
long long CountSubset(int* val, int n)
{
  
    // Number of odd length sub-sets
    long long ans = powmod(2, n - 1);
  
    // Sort the array
    sort(val, val + n);
    for (int i = 0; i < n; ++i) {
        int j = i + 1;
  
        // Checking each element for leftmost middle
        // element while they are equal
        while (j < n && val[j] == val[i]) {
  
            // Calculate the number of elements in
            // right of rightmost middle element
            int r = n - 1 - j;
  
            // Calculate the number of elements in
            // left of leftmost middle element
            int l = i;
  
            // Add selected even length subsets
            // to the answer
            ans = (ans + arr[l + r][l]) % mod;
            j++;
        }
    }
  
    return ans;
}
  
// Driver code
int main()
{
    Preprocess();
    int val[] = { 2, 3, 2 };
    int n = sizeof(val) / sizeof(val[0]);
    cout << CountSubset(val, n) << endl;
  
    return 0;
}

Java

// Java implementation of the above approach
import java.util.Arrays;
  
class GFG 
{
  
    static long mod = 1000000007;
    static long[][] arr = new long[1001][1001];
  
    // Function to store pascal triangle in 2-d array 
    static void Preprocess() 
    {
        arr[0][0] = 1;
        for (int i = 1; i <= 1000; ++i)
        {
            arr[i][0] = 1;
            for (int j = 1; j < i; ++j) 
            {
                arr[i][j] = (arr[i - 1][j - 1] + arr[i - 1][j]) % mod;
            }
            arr[i][i] = 1;
        }
    }
  
    // Function to return a raised to the power n 
    // with complexity O(log(n)) 
    static long powmod(long a, long n) 
    {
        if (n == 0)
        {
            return 1;
        }
        long pt = powmod(a, n / 2);
        pt = (pt * pt) % mod;
        if (n % 2 == 1) 
        {
            return (pt * a) % mod;
        } 
        else
        {
            return pt;
        }
    }
  
    // Function to return the number of sub-sets 
    // whose median is also present in the set 
    static long CountSubset(int[] val, int n)
    {
  
        // Number of odd length sub-sets 
        long ans = powmod(2, n - 1);
  
        // Sort the array 
        Arrays.sort(val);
        for (int i = 0; i < n; ++i) 
        {
            int j = i + 1;
  
            // Checking each element for leftmost middle 
            // element while they are equal 
            while (j < n && val[j] == val[i])
            {
  
                // Calculate the number of elements in 
                // right of rightmost middle element 
                int r = n - 1 - j;
  
                // Calculate the number of elements in 
                // left of leftmost middle element 
                int l = i;
  
                // Add selected even length subsets 
                // to the answer 
                ans = (ans + arr[l + r][l]) % mod;
                j++;
            }
        }
  
        return ans;
    }
  
    // Driver code 
    public static void main(String[] args)
    {
        Preprocess();
        int val[] = {2, 3, 2};
        int n = val.length;
  
        System.out.println(CountSubset(val, n));
    }
}
  
// This code contributed by Rajput-Ji

Python3

# Python3 implementation of the approach 
mod = 1000000007 
arr = [[None for i in range(1001)] for j in range(1001)] 
  
# Function to store pascal triangle in 2-d array 
def Preprocess(): 
   
    arr[0][0] = 1 
    for i in range(1, 1001):  
        arr[i][0] = 1 
        for j in range(1, i):  
            arr[i][j] = (arr[i - 1][j - 1] + arr[i - 1][j]) % mod 
           
        arr[i][i] = 1 
       
# Function to return a raised to the power n 
# with complexity O(log(n)) 
def powmod(a, n): 
   
    if not n: 
        return 1 
    pt = powmod(a, n // 2) 
    pt = (pt * pt) % mod 
    if n % 2: 
        return (pt * a) % mod 
    else:
        return pt 
  
# Function to return the number of sub-sets 
# whose median is also present in the set 
def CountSubset(val, n): 
   
    # Number of odd length sub-sets 
    ans = powmod(2, n - 1) 
  
    # Sort the array 
    val.sort() 
    for i in range(0, n):  
        j = i + 1 
  
        # Checking each element for leftmost middle 
        # element while they are equal 
        while j < n and val[j] == val[i]:  
  
            # Calculate the number of elements in 
            # right of rightmost middle element 
            r = n - 1 - j 
  
            # Calculate the number of elements in 
            # left of leftmost middle element 
            l = i 
  
            # Add selected even length 
            # subsets to the answer 
            ans = (ans + arr[l + r][l]) % mod 
            j += 1
  
    return ans 
   
# Driver code 
if __name__ == "__main__": 
   
    Preprocess() 
    val = [2, 3, 2]
    n = len(val) 
    print(CountSubset(val, n))
  
# This code is contributed by Rituraj Jain

C#

// C# implementation of the above approach
using System;
      
class GFG 
{
  
    static long mod = 1000000007;
    static long [,]arr = new long[1001,1001];
  
    // Function to store pascal triangle in 2-d array 
    static void Preprocess() 
    {
        arr[0,0] = 1;
        for (int i = 1; i <= 1000; ++i)
        {
            arr[i,0] = 1;
            for (int j = 1; j < i; ++j) 
            {
                arr[i,j] = (arr[i - 1,j - 1] + arr[i - 1,j]) % mod;
            }
            arr[i,i] = 1;
        }
    }
  
    // Function to return a raised to the power n 
    // with complexity O(log(n)) 
    static long powmod(long a, long n) 
    {
        if (n == 0)
        {
            return 1;
        }
        long pt = powmod(a, n / 2);
        pt = (pt * pt) % mod;
        if (n % 2 == 1) 
        {
            return (pt * a) % mod;
        } 
        else
        {
            return pt;
        }
    }
  
    // Function to return the number of sub-sets 
    // whose median is also present in the set 
    static long CountSubset(int[] val, int n)
    {
  
        // Number of odd length sub-sets 
        long ans = powmod(2, n - 1);
  
        // Sort the array 
        Array.Sort(val);
        for (int i = 0; i < n; ++i) 
        {
            int j = i + 1;
  
            // Checking each element for leftmost middle 
            // element while they are equal 
            while (j < n && val[j] == val[i])
            {
  
                // Calculate the number of elements in 
                // right of rightmost middle element 
                int r = n - 1 - j;
  
                // Calculate the number of elements in 
                // left of leftmost middle element 
                int l = i;
  
                // Add selected even length subsets 
                // to the answer 
                ans = (ans + arr[l + r,l]) % mod;
                j++;
            }
        }
  
        return ans;
    }
  
    // Driver code 
    public static void Main(String[] args)
    {
        Preprocess();
        int []val = {2, 3, 2};
        int n = val.Length;
  
        Console.WriteLine(CountSubset(val, n));
    }
}
  
/* This code contributed by PrinciRaj1992 */
输出:
5

时间复杂度: O(N 2 )