http://codeforces.com/contest/397/problem/C

给出n个数字,m = a[1] * a[2] * a[3] ... * a[n]

要求把m分成n个不一样的乘积,求方案数。

就是35分成2分的话,1 * 35 。35 * 1。5 * 7。7 * 5

首先数字很大,表示出来是不可能的。

考虑储存它的质因数,例如12。 12 = 2 * 2 * 3

如果要分成4分的话,首先对每一种质因数放。

例如2,有2个,可以表示为(4份)

2 * 2 * 1 * 1

2 * 1 * 2 * 1

......

4 * 1 * 1 * 1

..........

这是一个经典的组合数学问题,n个球,放在m个箱子,可以空,可以重叠。一共有C(n + m - 1, m - 1)种。

这里空的用了1来表示。

然后不对呀,这不是12的分解情况,它还有一个质因子嘛,3.

分成

3 * 1 * 1 * 1

1 * 3 * 1 * 1

1 * 1 * 3 * 1

1 * 1 * 1 * 3

,然后种数相乘,就是答案,为什么呢?比如(2 * 2 * 1 * 1) X (3 * 1 * 1 * 1) = (6 * 2 * 1 * 1),是一种情况。

因为有500个数字,如果每个数字都是2^30次方,一共有15000个2,但是格子最多500个。

可以预处理组合数C[15000][500]即可,不会爆内存,

一开始一直re,是我自己没分析好。、

最后也没预处理,因为没想到用C[15000][500]这样, 用的是逆元。我太水了太渣了

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. #define IOS ios::sync_with_stdio(false)
  7. using namespace std;
  8. #define inf (0x3f3f3f3f)
  9. typedef long long int LL;
  10. #define MY "H:/CodeBlocks/project/CompareTwoFile/DataMy.txt", "w", stdout
  11. #define ANS "H:/CodeBlocks/project/CompareTwoFile/DataAns.txt", "w", stdout
  12.  
  13. #include <iostream>
  14. #include <sstream>
  15. #include <vector>
  16. #include <set>
  17. #include <map>
  18. #include <queue>
  19. #include <string>
  20. map<int, int>mp;
  21. const int MOD = 1e9 + ;
  22. LL quick_pow(LL a, LL b, LL MOD) { //求解 a^b%MOD的值
  23. LL base = a % MOD;
  24. LL ans = ; //相乘,所以这里是1
  25. while (b) {
  26. if (b & ) {
  27. ans = (ans * base) % MOD; //如果这里是很大的数据,就要用quick_mul
  28. }
  29. base = (base * base) % MOD; //notice。注意这里,每次的base是自己base倍
  30. b >>= ;
  31. }
  32. return ans;
  33. }
  34. LL C(LL n, LL m, LL MOD) {
  35. if (n < m) return ; //防止sb地在循环,在lucas的时候
  36. if (n == m) return ;
  37. LL ans1 = ;
  38. LL ans2 = ;
  39. LL mx = max(n - m, m); //这个也是必要的。能约就约最大的那个
  40. LL mi = n - mx;
  41. for (int i = ; i <= mi; ++i) {
  42. ans1 = ans1 * (mx + i) %MOD;
  43. ans2 = ans2 * i % MOD;
  44. }
  45. return (ans1 * quick_pow(ans2, MOD - , MOD) % MOD); //这里放到最后进行,不然会很慢
  46. }
  47.  
  48. void work() {
  49. mp.clear();
  50. int n;
  51. scanf("%d", &n);
  52. for (int i = ; i <= n; ++i) {
  53. int x;
  54. scanf("%d", &x);
  55. int end = (int)sqrt(x + 0.5);
  56. for (int j = ; j <= end; ++j) {
  57. if (x % j == ) {
  58. mp[j]++;
  59. x /= j;
  60. while (x % j == ) {
  61. mp[j]++;
  62. x /= j;
  63. }
  64. end = (int)sqrt(x + 0.5);
  65. }
  66. }
  67. if (x != ) mp[x]++;
  68. }
  69. LL ans = ;
  70. for (map<int, int> :: iterator it = mp.begin(); it != mp.end(); ++it) {
  71. // cout << it->first << " " << it->second << endl;
  72. int val = it->second;
  73. // if (val > maxn) while(1);
  74. // ans *= C[val + n - 1][n - 1];
  75. ans *= C(val + n - , n - , MOD);
  76. ans %= MOD;
  77. }
  78. printf("%I64d\n", ans);
  79. }
  80. int main() {
  81. #ifdef local
  82. freopen("data.txt","r",stdin);
  83. #endif
  84. work();
  85. return ;
  86. }

C. On Number of Decompositions into Multipliers 组合数学的更多相关文章

  1. Codeforces396A - On Number of Decompositions into Multipliers

    Portal Description 给出\(n(n\leq500)\)个\([1,10^9]\)的数,令\(m=\prod_{i=1}^n a_i\).求有多少个有序排列\(\{a_n\}\),使得 ...

  2. cf C On Number of Decompositions into Multipliers

    题意:给你n个数,然后把这个n个数的乘积化成n个数相乘,可以化成多少个. 思路:分解质因数,求出每一个质因子的个数,然后用组合数学中隔板法把这些质因子分成n分,答案就是所有质因子划分成n份的情况的乘积 ...

  3. Codeforces Round #232 (Div. 1)

    这次运气比较好,做出两题.本来是冲着第3题可以cdq分治做的,却没想出来,明天再想好了. A. On Number of Decompositions into Multipliers 题意:n个数a ...

  4. Codeforces Round #232 (Div. 1) A 解题报告

    A. On Number of Decompositions into Multipliers 题目连接:http://codeforces.com/contest/396/problem/A 大意: ...

  5. Codeforces Round #232 (Div. 2) C

    C. On Number of Decompositions into Multipliers time limit per test 1 second memory limit per test 2 ...

  6. POJ3252——Round Number(组合数学)

    Round Numbers DescriptionThe cows, as you know, have no fingers or thumbs and thus are unable to pla ...

  7. poj 1019 Number Sequence 【组合数学+数字x的位宽函数】

    题目地址:http://poj.org/problem?id=1019 Number Sequence Time Limit: 1000MS   Memory Limit: 10000K Total ...

  8. poj3252-Round Number 组合数学

    题目: Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8492   Accepted: 2963 ...

  9. 2019长安大学ACM校赛网络同步赛 J Binary Number(组合数学+贪心)

    链接:https://ac.nowcoder.com/acm/contest/897/J 来源:牛客网 Binary Number 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32 ...

随机推荐

  1. codeforces A. Array 解题报告

    题目链接:http://codeforces.com/problemset/problem/300/A 题目意思:给出n个数,将它们分成三批:1.所有数相乘的结果 < 0    2.所有数相乘的 ...

  2. Linux档案属性

    输入命令:ls -al 档案类型权限: 第一個字元代表这个档案是『目录.档案或链接档等等』: 当为[ d ]则是目录: 当为[ - ]则是目录: 若是[ l ]则表示为链接档(link file): ...

  3. Constructing Roads In JGShining's Kingdom

    点击打开题目链接 本题目是考察  最长递增子序列的  有n^2     n(logn)  n^2  会超时的 下面两个方法的代码  思路  可以百度LIS  LCS dp里面存子序列 n(logn) ...

  4. python之yield和Generator

    首先我们从一个小程序导入,各定一个list,找出其中的素数,我们会这样写 import math def is_Prims(number): if number == 2: return True / ...

  5. POJ3061 Subsequence

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16520   Accepted: 7008 Desc ...

  6. POJ2217(最长公共子串)

    Secretary Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 992   Accepted: 408 Descripti ...

  7. .NETFramework:Timers

    ylbtech-.NETFramework:Timers 1.返回顶部 1. #region 程序集 System, Version=4.0.0.0, Culture=neutral, PublicK ...

  8. android项目源码

    [置顶] Android精品开源项目整理_V20140221(持续更新中..) 让我们回顾下2013年有哪些精品资源:Android精品开源项目整理_V20131115(持续更新中..) 引言:   ...

  9. socket辅助类

    using System; using System.Collections; using System.Net; using System.Net.Sockets; using System.Tex ...

  10. linux之打包压缩命令

    tar:主选项:[一条命令以下5个参数只能有一个]-c: --create 新建一个压缩文档,即打包-x: --extract,--get解压文件-t: --list,查看压缩文档里的文件目录-r:- ...