给定大小为N的数组arr [] ,任务是计算我们可以从给定数组元素中选择一个子集的方式的数量,以使所选子集的中位数也作为子集中的元素出现。由于此数字可能很大,因此请对1000000007取模。
例子:
Input: arr[] = {2, 3, 2}
Output: 5
{2}, {3}, {2}, {2, 2} and {2, 3, 2} are all possible valid sub-sets.
Input: arr[] = {1, 4, 2, 2, 3, 5}
Output: 36
方法:
- 每个奇数大小的子集在子集中都有其中位数,因此,我们可以直接在答案中加上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 )