题解:P6298 齿轮
_Chronostatis_ · · 题解
题意
给定
思路
我们先来观察最大公因数的性质,若
我们可以对一个数计算出其倍数的个数
时间复杂度:
空间复杂度:
:::info[对题解审核员的声明] 这篇题解的代码在时间、空间复杂度上均没有问题,且讨论区仍有题解没有声明时间、空间复杂度,因此我不能理解您对这篇题解的评价,并且请您评价时留下名字,方便私信交流。 :::
:::info[代码]
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 1e6 + 10, MOD = 1e9 + 7;
int n, m, k, a[MAXN], cnt[MAXN];
ll ans[MAXN], fac[MAXN], inv[MAXN];
ll qpow(ll x, ll y) {
ll res = 1;
for (; y; y >>= 1, (x *= x) %= MOD) {
if (y & 1) (res *= x) %= MOD;
}
return res;
}
void Init(int _n) {
fac[0] = inv[0] = 1;
for (int i = 1; i <= _n; i++) {
fac[i] = fac[i - 1] * i % MOD;
}
inv[_n] = qpow(fac[_n], MOD - 2);
for (int i = _n; i > 1; i--) {
inv[i - 1] = inv[i] * i % MOD;
}
}
ll C(int n, int m) {
return fac[n] * inv[m] % MOD * inv[n - m] % MOD;
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
cnt[a[i]]++;
}
Init(n);
for (int i = m; i >= 1; i--) {
int c = 0;
for (int j = i; j <= m; j += i) {
c += cnt[j];
}
ans[i] = C(c, k);
for (int j = i << 1; j <= m; j += i) {
ans[i] = (ans[i] - ans[j] + MOD) % MOD;
}
}
for (int i = 1; i <= m; i++) {
cout << ans[i] << ' ';
}
return 0;
}
:::