传送门
题解:
我们考虑算出 F [ d ] F[d] F[d]表示所有 d ∣ g c d d\mid gcd d∣gcd的方案之和,然后莫比乌斯反演就行了。
但是实际上我们发现从大往小算可以直接用减法来容斥,就不用莫比乌斯反演了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<22|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>
inline T get(){
char c;
while(!isdigit(c=gc()));T num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return num;
}
inline int gi(){return get<int>();}
}
using namespace IO;
using std::cerr;
using std::cout;
cs int mod=1e9+7;
inline int add(int a,int b){a+=b-mod;return a+(a>>31&mod);}
inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
inline int mul(int a,int b){ll r=(ll)a*b;return r>=mod?r%mod:r;}
inline int power(int a,int b,int res=1){
for(;b;b>>=1,a=mul(a,a))(b&1)&&(res=mul(res,a));
return res;
}
inline void Inc(int &a,int b){a+=b-mod;a+=a>>31&mod;}
inline void Dec(int &a,int b){a-=b;a+=a>>31&mod;}
inline void Mul(int &a,int b){a=mul(a,b);}
cs int N=3e5+7;
int fac[N],ifac[N];
inline void init(int lim){
fac[0]=fac[1]=1;
for(int re i=2;i<=lim;++i)fac[i]=mul(fac[i-1],i);
ifac[lim]=power(fac[lim],mod-2);
for(int re i=lim-1;~i;--i)ifac[i]=mul(ifac[i+1],i+1);
}
inline int C(int n,int m){return mul(fac[n],mul(ifac[m],ifac[n-m]));}
int n,m,k;
int cnt[N],F[N];
signed main(){
#ifdef zxyoi
freopen("gcd.in","r",stdin);//freopen("gcd.out","w",stdout);
#endif
n=gi(),m=gi(),k=gi();init(std::max(n,m));
for(int re i=1;i<=n;++i)++cnt[gi()];
for(int re i=1;i<=m;++i)
for(int re j=i+i;j<=m;j+=i)cnt[i]+=cnt[j];
int s=n-k;
for(int re i=m;i;--i){
if(cnt[i]<s)F[i]=0;
else {
F[i]=power(m/i,n-cnt[i],power(m/i-1,cnt[i]-s,C(cnt[i],s)));
for(int re j=i+i;j<=m;j+=i)Dec(F[i],F[j]);
}
}
for(int re i=1;i<=m;++i)cout<<F[i]<<" ";
return 0;
}