传送门(dark)
SOL
这个说的比较详细了,不再赘述。
CODE
#include<bits/stdc++.h>
#define pf printf
#define sf scanf
#define cs const
#define ll long long
#define db double
#define in red()
#define gc getchar()
using namespace std;
inline int red(){
int num=0,f=1;char c=gc ;
for(;!isdigit(c);c=gc)if(c=='-')f=-1;
for(;isdigit(c);c=gc)num=num*10+(c^48);
return num*f;
}
cs int N=3e5+10,mod=1e9+7;
#define ri register int
inline int add(cs int &a,cs int &b){return a+b>mod? a-mod+b:a+b;}
inline int dec(cs int &a,cs int &b){return a-b<0?a+mod-b:a-b;}
inline int mul(cs int &a,cs int &b){return 1ll*a*b%mod;}
inline int ksm(int a,int b){int ans=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ans=mul(ans,a);return ans;}
int mu[N],F[N],f[N],p[N],top,fac[N],ifac[N];
bool vis[N];
inline void init(int lim){
mu[1]=1;
for(ri i=2;i<=lim;++i){
if(!vis[i])p[++top]=i,mu[i]=-1;
for(ri j=1;j<=top&&1ll*p[j]*i<=lim;++j){
vis[i*p[j]]=1;
if(i%p[j]==0){
break;
}
mu[i*p[j]]=mu[i]*mu[p[j]];
}
}
fac[0]=1;ifac[0]=1;
for(ri i=1;i<=lim;++i)fac[i]=mul(fac[i-1],i),ifac[i]=mul(ifac[i-1],ksm(i,mod-2));
}
inline int C(cs int &a,cs int &b){
if(a==0)return 1;
return mul(fac[a],mul(ifac[b],ifac[a-b]));
}
int cnt,n,m,K,num[N];
signed main (){
n=in,m=in,K=in;
for(ri i=1;i<=n;++i){
int k=in;++num[k];
}
init(max(n,m));
for(ri d=m;d>=1;--d){
// cout<<"begin\n";
// cout<<d<<'\n';
cnt=num[d];
for(ri i=d*2,k=2;i<=m;i+=d,++k){
cnt+=num[i];
// cout<<cnt<<'\n';
if(mu[k]>0)f[d]=add(f[d],F[i]);
else if(mu[k]<0)f[d]=dec(f[d],F[i]);
}
if(cnt<n-K)continue;
F[d]=1ll*ksm(m/d,n-cnt)*C(cnt,n-K)%mod*ksm(m/d-1,cnt+K-n)%mod;
f[d]=add(f[d],F[d]);
// cout<<"end\n";
}
for(ri i=1;i<=m;++i)pf("%d ",f[i]);
return 0;
}