题目描述
Daniel13265 从不知哪里找来了 nn 个齿轮,第 ii 个齿轮的齿数为不超过 mm 的正整数 a_ia
i
。他现在想把其中 kk 个齿轮按照一定的方式拼接在一起。
当齿轮使用一段时间后,就会产生损耗。一个齿轮组的损耗速率是由这个齿轮组的所有齿轮齿数的最大公约数决定的:最大公约数越大,相同的齿之间啮合的频率就会增高,从而损耗的速率就会变快。这个最大公约数又被称为损耗因子。
算出一个齿轮组的损耗因子是很容易的。可是现在 Daniel13265 想要知道,对于可能拼接出的所有齿轮组的损耗因子。
Daniel13265 知道拼接出损耗因子大于 mm 的齿轮组是不可能的,而且由于可能拼出的齿轮组的个数很多,你只需要反过来告诉他对于所有的 t\in[1, m]t∈[1,m],能够拼接出的损耗因子为 tt 的齿轮组的个数对 10^9+710
9
+7 取模后的结果即可。
输入格式
输入共 2 行。
第一行包含三个正整数 n,m,分别表示 Daniel13265 拥有的齿轮个数,齿轮齿数的最大可能值与 Daniel13265 期望的齿轮组的齿轮个数。
第二行共 nn 个用单个空格隔开的正整数,第 i 个数 ai 表示第 i 个齿轮的齿数。
输出格式
输出一行 m 个整数,第 t 个数表示能够拼接出的损耗因子为 t 的齿轮组的个数对 10^9+7 取模后的结果。
输入输出样例
输入 #1
5 6 2
1 2 3 4 6
输出 #1
6 3 1 0 0 0
说明/提示
样例解释
损耗因子为 11 的齿轮组有 (1,2),(1,3),(1,4),(1,6),(2,3),(3,4) 共 6 个;
损耗因子为 22 的齿轮组有 (2,4),(2,6),(4,6) 共 3 个;
损耗因子为 33 的齿轮组有 (3,6) 共 1 个。
容斥
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const ll mod=1e9+7;
const int N=1e6+500;
ll f[N],inv[N],vis[N],ans[N];
ll qpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans;
}
void init(){
f[0]=1;
for(int i=1;i<N;++i){
f[i]=f[i-1]*i%mod;
}
inv[N-1]=qpow(f[N-1],mod-2);
for(int i=N-2;i>=0;--i){
inv[i]=inv[i+1]*(i+1)%mod;
}
}
ll C(ll n,ll m){
if(n<m)return 0;
return (f[n]*inv[m]%mod)*inv[n-m]%mod;
}
int main(){
init();
ll n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;++i){
int x;
scanf("%d",&x);
vis[x]++;
}
for(int i=m;i;--i){
ll cut=0;
for(int j=1;j*i<=m;++j){
cut+=vis[i*j];
ans[i]=(ans[i]-ans[i*j]+mod)%mod;
}
ans[i]=(ans[i]+C(cut,k)+mod)%mod;
}
for(int i=1;i<=m;++i){
printf("%lld ",ans[i]);
}
return 0;
}