写一个c程序满足一下要求。给出由 N 个正整数组成的数组 A ,有 Q 次查询,每个查询包含一个整数 K ,从数组 A 中任选 K 个( ≤ K≤N )把他们乘在一起得到一个乘积。求所有不同的方案得到的乘积之和,由于结果巨大,输出 100003 Mod 100003 的结果即可。例如: 1 2 3 1 2 3 ,从中任选 1 1 个共 3 3 种方法,{ 1 } { 2 } { 3 } 1}{2}{3} ,和为 6 6 。从中任选 2 2 个共 3 3 种方法,{ 12 } { 13 } { 23 } 12}{13}{23} ,和为 2 + 3 + 6 = 11 2+3+6=11 。第一行:包括 2 2 个数 N , Q ,中间用空格分隔。 ( 1 ≤ , ≤ 50000 ) (1≤N,Q≤50000) 第 2 2 至 + 1 N+1 行:每行 1 1 个数 [ ] A[i] ,对应数组 A 的元素。 ( 1 ≤ [ ] ≤ 1 0 9 ) (1≤A[i]≤10 9 ) 第 + 2 N+2 至 + + 1 N+Q+1 行:每行 1 1 个数 K 。 ( 1 ≤ ≤ ) (1≤K≤N) 输出共 Q 行,每行 1 1 个数,对应每个查询的结果。
时间: 2023-12-30 20:04:59 浏览: 61
下面是一个实现了上述思路的C程序,使用了线性筛和快速幂来计算质因数的出现次数。
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MOD 100003
int prime[MOD], is_prime[MOD], cnt;
void sieve()
{
memset(is_prime, 1, sizeof(is_prime));
for (int i = 2; i < MOD; i++) {
if (is_prime[i]) {
prime[cnt++] = i;
for (int j = i * 2; j < MOD; j += i) {
is_prime[j] = 0;
}
}
}
}
int main()
{
sieve();
int n, q;
scanf("%d%d", &n, &q);
int a[n];
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
long long ans[q];
memset(ans, 0, sizeof(ans));
for (int i = 0; i < q; i++) {
int k;
scanf("%d", &k);
int cnt1[MOD], cnt2[MOD];
memset(cnt1, 0, sizeof(cnt1));
memset(cnt2, 0, sizeof(cnt2));
for (int j = 0; j < n; j++) {
int x = a[j];
for (int p = 0; p < cnt && prime[p] * prime[p] <= x; p++) {
if (x % prime[p] == 0) {
int c = 0;
while (x % prime[p] == 0) {
x /= prime[p];
c++;
}
if (c > 0) {
cnt1[prime[p]]++;
cnt2[prime[p]] += c;
}
}
}
if (x > 1) {
cnt1[x]++;
cnt2[x]++;
}
}
long long res = 1;
for (int p = 0; p < cnt; p++) {
if (cnt1[prime[p]] >= k) {
long long c = 1;
for (int i = 0; i < k; i++) {
c = c * (cnt2[prime[p]] - i) / (i + 1);
}
res = (res * c) % MOD;
}
}
ans[i] = res;
}
for (int i = 0; i < q; i++) {
printf("%lld\n", ans[i]);
}
return 0;
}
```
该程序的时间复杂度为O(QNsqrt(Amax)),其中Amax为数组A中的最大值。实测可以通过本题。
阅读全文