传送门
考虑答案为 gcd 的倍数的情况就要好做很多
设 cnt 为 d 的倍数的个数
考虑容斥,发现
#include<bits/stdc++.h>
#define N 300050
using namespace std;
typedef long long ll;
const int Mod = 1000000007;
ll add(ll a, ll b){ return (a + b) % Mod;}
ll mul(ll a, ll b){ return a * b % Mod;}
ll power(ll a, ll b){ ll ans = 1;
for(;b;b>>=1){ if(b&1) ans = mul(ans, a); a = mul(a, a);}
return ans;
}
int n, m, k, a[N], cnt[N];
ll fac[N], ifac[N], F[N], f[N];
int prim[N], isp[N], mu[N], tot;
ll C(int n, int m){ return mul(mul(fac[n], ifac[n-m]), ifac[m]);}
void prework(){
mu[1] = 1;
for(int i = 2; i <= m; i++){
if(!isp[i]) prim[++tot] = i, mu[i] = -1;
for(int j = 1; j <= tot; j++){
if(i * prim[j] > m) break;
isp[i * prim[j]] = 1;
if(i % prim[j] == 0){ mu[i * prim[j]] = 0; break;}
mu[i * prim[j]] = mu[i] * mu[prim[j]];
}
}
}
int main(){
scanf("%d%d%d", &n, &m, &k); prework();
fac[0] = fac[1] = ifac[0] = ifac[1] = 1;
for(int i = 2; i <= n; i++) fac[i] = mul(fac[i-1], i);
ifac[n] = power(fac[n], Mod - 2);
for(int i = n-1; i >= 2; i--) ifac[i] = mul(ifac[i+1], i+1);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]), cnt[a[i]]++;
for(int i = 1; i <= m; i++)
for(int j = i << 1; j <= m; j += i) cnt[i] += cnt[j];
for(int i = 1; i <= m; i++){
if(cnt[i] - (n-k) < 0) continue;
int tmp = n - cnt[i];
F[i] = mul(mul(power(m/i, tmp), C(cnt[i], k-tmp)), power(m/i-1, k-tmp));
}
for(int i = 1; i <= m; i++){
for(int j = 1; j * i <= m; j++) f[i] = add(f[i], mul(F[i*j], mu[j]));
}
for(int i = 1; i <= m; i++) cout << f[i] << " ";
return 0;
}