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

2014-11-24 09:55:00 · 作者: · 浏览: 0

题目大意:给出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 
  
   
#include 
   
     #include 
    
      #include
      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
      
        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
       
        ::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; }