题目链接:Codeforces 396A On Number of Decompositions into Multipliers
题目大意:给出n个数,ai,然后取这n个数的积为m,计算将m分解成n个因子,问有多少种有序因子序列。
解题思路:n为500,ai的上限为1e9,所以要表示m是完全不可能的,但是记录下m的因子个数是完全可以的,因为ai就是m的因子,所以把ai分解成质因子然后离散保存个数。
接下来枚举每种因子的分配情况,假如因子t有k个,那么将k个因子分配到n个位置的方式数即为C(k+n-1, n-1),这是组合数学中的隔板法,要将m个糖果分成n份的方法数即为C(m-1,n-1),即将糖果排成一排,然后枚举任意两个糖果之间放一个隔板,(这样会保证说每一份都会有至少一个糖果,但是这道题有点不同,有些数可能没有分到这个因子);k+n-1个位置,选n-1个位置放隔板,其他的就是因子,然后每两个板之间的因子个数就对应着某个数含有该因子的个数。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <map>
using namespace std;
typedef long long ll;
const int N = 17000;
const int M = 1000;
const int mod = 1e9+7;
int n, k;
ll c[N][M];
map<int, int> g;
void init () {
c[0][0] = 1;
for (int i = 1; i < N; i++) {
for (int j = 0; j <= i && j < M; j++) {
if (j == 0 || j == i) c[i][j] = 1;
else c[i][j] = (c[i-1][j-1] + c[i-1][j])%mod;
}
}
}
void solve (ll k) {
for (int j = 2; j * j <= k; j++) if (k % j == 0) {
int cnt = 0;
while (k%j == 0) {
k /= j;
cnt++;
}
g[j] += cnt;
}
if (k > 1) g[k] += 1;
}
int main () {
init();
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &k);
solve(k);
}
ll ans = 1;
for (map<int, int>::iterator i = g.begin(); i != g.end(); i++) {
int t = (*i).second;
ans = (ans * c[t+n-1][n-1]) % mod;
}
cout << ans << endl;
return 0;
}