原题链接
考察:组合数学
错误思路:
隔板法忘光了,没做出来= =
思路:
很容易想到是分解质因数,然后将质因数安排在\(n\)个位置上.这里比较容易想到隔板法,但是注意常规隔板法是需要\(x_i>=1\),所以我们需要将\(x_i+n-1\).还有一个就是质因数排序问题,注意到案例三\(5,7\)做一次隔板少了\(7,5\)这一种情况.将质因数分类考虑,每个做隔板法再相乘即可.
#include <iostream> #include <cstring> #include <map> using namespace std; typedef long long LL; const int N = 510,M = 1000000007,S = 20010; int a[N],n; map<int,int> mp; LL fact[S],infact[S]; void GetDivide(int n) { for(int i=2;i<=n/i;i++) { if(n%i==0) while(n%i==0) n/=i,mp[i]++; } if(n>1) mp[n]++; } int qsm(int a,int k,int m) { int res = 1; while(k) { if(k&1) res = (LL)res*a%m; a = (LL)a*a%m; k>>=1; } return res; } void init() { fact[0] = 1,infact[0] = 1; for(int i=1;i<S;i++) { fact[i] = (LL)fact[i-1]*i%M; infact[i] = (LL)infact[i-1]*qsm(i,M-2,M)%M; } } LL C(int a,int b) { if(a<b) return 0; return fact[a]*infact[b]%M*infact[a-b]%M; } int main() { scanf("%d",&n); init(); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); GetDivide(a[i]); } int res = 1; for(auto& it:mp) { int x = it.second; res = (LL)res*C(x+n-1,n-1)%M; } printf("%d\n",res); return 0; }