标签:整数 sample string otc space lld += sam include
3 3 3
3 3 3
7 1 0
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int mod=1000000007; int n,m,k,t[300003]; ll fac[300003],inv[300003],f[300003]; inline ll Pow(ll x,int y){ ll res=1; for(;y;y>>=1){ if(y&1) res=res*x%mod; x=x*x%mod; }return res; } inline ll C(int N,int M) {return fac[N]*inv[M]%mod*inv[N-M]%mod;} int main(){ scanf("%d%d%d",&n,&m,&k); int q; fac[0]=inv[0]=1; for(int i=1;i<=n;++i){ scanf("%d",&q),++t[q]; //开个桶存起来 fac[i]=fac[i-1]*i%mod; inv[i]=inv[i-1]*Pow((ll)i,mod-2)%mod; //预处理出阶乘以及其逆元 } for(int i=1;i<=m;++i){ int cnt=0; for(int j=i;j<=m;j+=i) cnt+=t[j]; //统计i的倍数的个数 if(cnt<n-k) continue; f[i]=C(cnt,n-k)*Pow((ll)(m/i-1),cnt-n+k)%mod*Pow((ll)(m/i),n-cnt)%mod;
//f[i]=对i的倍数强制修改的方案*其他非i倍数的修改方案数 } for(int i=m;i;--i) //逆序筛去gcd为i的倍数的情况 for(int j=i*2;j<=m;j+=i) f[i]=(f[i]-f[j]+mod)%mod; for(int i=1;i<=m;++i) printf("%lld ",f[i]); return 0; }
标签:整数 sample string otc space lld += sam include
原文地址:https://www.cnblogs.com/kafuuchino/p/9709390.html