给定一个由 n 个不同元素组成的整数数组 arr[] ,以及一个正整数 k ( k < = n)。任务是从给定的数组中计算大小为 k 的所有排序子集的乘积,使用索引完全除以 k 的元素。
注意:由于答案可能非常大,以 10^9 7.为模打印
示例:
输入: arr[] = {4,7,5,9,3},k = 4 输出: 808556639 解释: 在这种情况下有 5 个可能的集合: {4,7,5,9} - > 180(排序顺序{4,5,7,9}:索引 1,2,4 除 m,所以集合的值为 4 * 5 * 9 = 180) 3} - > 108 {4,7,5,3} - > 84 {7,5,9,3} - > 135 合计值=(180 * 108 * 108 * 84 * 135)%(109 7)= 808556639
输入: arr[] = {7,8,9},k = 2 输出: 254016
天真方法:
我们可以找到大小为 k 的所有子集,然后对子集进行排序,找到每个子集的值并相乘,得到最终的答案。 由于可以有 2 个 n 子集,这种方法对于大的 n 值来说效率不是很高
有效方法:
- 其思想不是创建所有子集来寻找答案,而是计算所有子集内每个元素的计数。如果我们找到所有子集中每个元素的计数,那么答案将是
-
为了找到 arr[i]的计数,我们必须找到不同子集的总数,这些子集可以通过将 arr[i]放置在将 k 完全除的每个可能的索引处而形成。
-
通过将 arr[i]放置在第 j 个索引处(j 完全除 k)形成的集合数将为:
(小于 arr[i]的元素总数) c j-1 * (大于 arr[i]的元素总数)ck-jt10】
- 由于任何元素的计数都可能很大,所以要求(arr[i](arr[i]))%(109 7)我们就要用到 费马小定理 也就是
{ a(p-1)mod p = 1 } =>{(ax)% p =(a(x % p-1))% p。
所以,利用费马小定理
(arr[i](arr[i]))%(109 7)=>(arr[i](arr[i]% 109 6))%(109 7)。
下面是上述方法的实现:
c
// c implementation of the above approach
#include
using namespace std;
int p = 1000000007;
// iterative function to calculate
// (x^y)%p in o(log y)
long long int power(long long int x,
long long int y,
long long int p)
{
long long int res = 1;
x = x % p;
while (y > 0) {
// if y is odd, multiply
// x with result
if (y & 1)
res = (res * x) % p;
// y must be even now
y = y >> 1;
x = (x * x) % p;
}
return res;
}
// iterative function to calculate
// (ncr)%p and save in f[n][r]
void ncr(long long int n, long long int p,
int f[][100], int m)
{
for (long long int i = 0; i <= n; i ) {
for (long long int j = 0; j <= m; j ) {
// if j>i then c(i, j) = 0
if (j > i) {
f[i][j] = 0;
}
// if iis equal to j then
// c(i, j) = 1
else if (j == 0 || j == i) {
f[i][j] = 1;
}
else {
f[i][j] = (f[i - 1][j]
f[i - 1][j - 1])
% p;
}
}
}
}
// function calculate the final answer
void productofsubsets(int arr[], int n,
int m)
{
int f[n 1][100];
ncr(n, p - 1, f, m);
sort(arr, arr n);
// initialize ans
long long int ans = 1;
for (long long int i = 0; i < n; i ) {
// x is count of occurence of arr[i]
// in different set such that index
// of arr[i] in those sets divides
// k completely.
long long int x = 0;
for (long long int j = 1; j <= m; j ) {
// finding the count of arr[i] by
// placing it at index which
// divides k completely
if (m % j == 0) {
// by fermat's theorem
x = (x
(f[n - i - 1][m - j]
* f[i][j - 1])
% (p - 1))
% (p - 1);
}
}
ans
= ((ans * power(arr[i], x, p)) % p);
}
cout << ans << endl;
}
// driver code
int main()
{
int arr[] = { 4, 5, 7, 9, 3 };
int k = 4;
int n = sizeof(arr) / sizeof(arr[0]);
productofsubsets(arr, n, k);
return 0;
}
java 语言(一种计算机语言,尤用于创建网站)
// java implementation of the above approach
import java.util.*;
class gfg{
static int p = 1000000007;
// iterative function to calculate
// (x^y)%p in o(log y)
static int power(int x, int y, int p)
{
int res = 1;
x = x % p;
while (y > 0)
{
// if y is odd, multiply
// x with result
if (y % 2 == 1)
res = (res * x) % p;
// y must be even now
y = y >> 1;
x = (x * x) % p;
}
return res;
}
// iterative function to calculate
// (ncr)%p and save in f[n][r]
static void ncr(int n, int p,
int f[][], int m)
{
for(int i = 0; i <= n; i )
{
for(int j = 0; j <= m; j )
{
// if j>i then c(i, j) = 0
if (j > i)
{
f[i][j] = 0;
}
// if iis equal to j then
// c(i, j) = 1
else if (j == 0 || j == i)
{
f[i][j] = 1;
}
else
{
f[i][j] = (f[i - 1][j]
f[i - 1][j - 1]) % p;
}
}
}
}
// function calculate the final answer
static void productofsubsets(int arr[], int n,
int m)
{
int [][]f = new int[n 1][100];
ncr(n, p - 1, f, m);
arrays.sort(arr);
// initialize ans
long ans = 1;
for(int i = 0; i < n; i )
{
// x is count of occurence of arr[i]
// in different set such that index
// of arr[i] in those sets divides
// k completely.
int x = 0;
for(int j = 1; j <= m; j )
{
// finding the count of arr[i] by
// placing it at index which
// divides k completely
if (m % j == 0)
{
// by fermat's theorem
x = (x (f[n - i - 1][m - j] *
f[i][j - 1]) %
(p - 1)) %
(p - 1);
}
}
ans = ((ans * power(arr[i], x, p)) % p);
}
system.out.print(ans "\n");
}
// driver code
public static void main(string[] args)
{
int arr[] = { 4, 5, 7, 9, 3 };
int k = 4;
int n = arr.length;
productofsubsets(arr, n, k);
}
}
// this code is contributed by rajput-ji
python 3
# python3 implementation of the above approach
p = 1000000007
# iterative function to calculate
# (x^y)%p in o(log y)
def power(x, y, p):
res = 1
x = x % p
while (y > 0):
# if y is odd, multiply
# x with result
if (y & 1):
res = (res * x) % p
# y must be even now
y = y >> 1
x = (x * x) % p
return res
# iterative function to calculate
# (ncr)%p and save in f[n][r]
def ncr(n, p, f, m):
for i in range(n 1):
for j in range(m 1):
# if j>i then c(i, j) = 0
if (j > i):
f[i][j] = 0
# if i is equal to j then
# c(i, j) = 1
elif(j == 0 or j == i):
f[i][j] = 1
else:
f[i][j] = (f[i - 1][j]
f[i - 1][j - 1]) % p
# function calculate the final answer
def productofsubsets(arr, n, m):
f = [[0 for i in range(100)]
for j in range(n 1)]
ncr(n, p - 1, f, m)
arr.sort(reverse = false)
# initialize ans
ans = 1
for i in range(n):
# x is count of occurence of arr[i]
# in different set such that index
# of arr[i] in those sets divides
# k completely.
x = 0
for j in range(1, m 1, 1):
# finding the count of arr[i] by
# placing it at index which
# divides k completely
if (m % j == 0):
# by fermat's theorem
x = ((x (f[n - i - 1][m - j] *
f[i][j - 1]) %
(p - 1)) %
(p - 1))
ans = ((ans * power(arr[i], x, p)) % p)
print(ans)
# driver code
if __name__ == '__main__':
arr = [ 4, 5, 7, 9, 3 ]
k = 4
n = len(arr);
productofsubsets(arr, n, k)
# this code is contributed by samarth
c
// c# implementation of the above approach
using system;
class gfg{
static int p = 1000000007;
// iterative function to calculate
// (x^y)%p in o(log y)
static int power(int x, int y, int p)
{
int res = 1;
x = x % p;
while (y > 0)
{
// if y is odd, multiply
// x with result
if (y % 2 == 1)
res = (res * x) % p;
// y must be even now
y = y >> 1;
x = (x * x) % p;
}
return res;
}
// iterative function to calculate
// (ncr)%p and save in f[n,r]
static void ncr(int n, int p,
int [,]f, int m)
{
for(int i = 0; i <= n; i )
{
for(int j = 0; j <= m; j )
{
// if j>i then c(i, j) = 0
if (j > i)
{
f[i, j] = 0;
}
// if iis equal to j then
// c(i, j) = 1
else if (j == 0 || j == i)
{
f[i, j] = 1;
}
else
{
f[i, j] = (f[i - 1, j]
f[i - 1, j - 1]) % p;
}
}
}
}
// function calculate the final answer
static void productofsubsets(int []arr, int n,
int m)
{
int [,]f = new int[n 1, 100];
ncr(n, p - 1, f, m);
array.sort(arr);
// initialize ans
long ans = 1;
for(int i = 0; i < n; i )
{
// x is count of occurence of arr[i]
// in different set such that index
// of arr[i] in those sets divides
// k completely.
int x = 0;
for(int j = 1; j <= m; j )
{
// finding the count of arr[i] by
// placing it at index which
// divides k completely
if (m % j == 0)
{
// by fermat's theorem
x = (x (f[n - i - 1, m - j] *
f[i, j - 1]) %
(p - 1)) %
(p - 1);
}
}
ans = ((ans * power(arr[i], x, p)) % p);
}
console.write(ans "\n");
}
// driver code
public static void main(string[] args)
{
int []arr = { 4, 5, 7, 9, 3 };
int k = 4;
int n = arr.length;
productofsubsets(arr, n, k);
}
}
// this code is contributed by rajput-ji
java 描述语言
output:
808556639
时间复杂度: (n * k)
辅助空间:o(n * 100)t4】
麻将胡了pg电子网站的版权属于:月萌api www.moonapi.com,转载请注明出处