`
阿尔萨斯
  • 浏览: 4147996 次
社区版块
存档分类
最新评论

Codeforces 396A On Number of Decompositions into Multipliers(组合数学)

 
阅读更多

题目链接: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;
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics