5648. 生成乘积数组的方案数(质因数分解&组合数学)
思路:质因数分解+组合数学。
将 k k k进行质因数分解后,考虑对于某一个质因数的个数 c n t cnt cnt,如何分配给个 n n n个位置,可以为空。
这等价于把 c n t cnt cnt个球放入 n n n个篮子,篮子可以为空的方案。
我们可以先将 n n n个篮子都加入一个球,问题等价于 c n t + n cnt+n cnt+n个球放入 n n n个篮子,篮子不能为空的方案数,这可以用隔板法解决。
a n s = C ( c n t + n − 1 , n − 1 ) = C ( c n t + n − 1 , c n t ) ans=C(cnt+n-1,n-1)=C(cnt+n-1,cnt) ans=C(cnt+n−1,n−1)=C(cnt+n−1,cnt) ,在 c n t + n − 1 cnt+n-1 cnt+n−1个可以放隔板的位置放入 n − 1 n-1 n−1个隔板,这样就分成了 n n n个部分。
最后答案都乘起来就行了。
代码
typedef long long ll;
const int N=1e4+5,mod=1e9+7;
ll fac[N];
class Solution {
public:
ll ksm(ll a,ll n){
ll s=1;
while(n){
if(n&1) s=s*a%mod;
a=a*a%mod;
n>>=1;
}return s;
}
ll C(ll m,ll n){
return fac[m]*ksm(fac[n]*fac[m-n]%mod,mod-2)%mod;
}
vector<int> waysToFillArray(vector<vector<int>>& q) {
fac[0]=1;for(int i=1;i<N;i++) fac[i]=fac[i-1]*i%mod;
vector<int>res;
for(auto v:q){
ll ans=1;
int n=v[0],k=v[1];
for(int i=2;i*i<=k;i++){
if(k%i==0){
int s=0;
while(k%i==0) k/=i,s++;
ans=ans*C(n+s-1,s)%mod;
}
}
if(k>1) ans=ans*n%mod;
res.push_back(ans);
}
return res;
}
};