C. On Number of Decompositions into Multipliers 组合数学
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]这样, 用的是逆元。我太水了太渣了
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <cmath>
- #include <algorithm>
- #define IOS ios::sync_with_stdio(false)
- using namespace std;
- #define inf (0x3f3f3f3f)
- typedef long long int LL;
- #define MY "H:/CodeBlocks/project/CompareTwoFile/DataMy.txt", "w", stdout
- #define ANS "H:/CodeBlocks/project/CompareTwoFile/DataAns.txt", "w", stdout
- #include <iostream>
- #include <sstream>
- #include <vector>
- #include <set>
- #include <map>
- #include <queue>
- #include <string>
- map<int, int>mp;
- const int MOD = 1e9 + ;
- LL quick_pow(LL a, LL b, LL MOD) { //求解 a^b%MOD的值
- LL base = a % MOD;
- LL ans = ; //相乘,所以这里是1
- while (b) {
- if (b & ) {
- ans = (ans * base) % MOD; //如果这里是很大的数据,就要用quick_mul
- }
- base = (base * base) % MOD; //notice。注意这里,每次的base是自己base倍
- b >>= ;
- }
- return ans;
- }
- LL C(LL n, LL m, LL MOD) {
- if (n < m) return ; //防止sb地在循环,在lucas的时候
- if (n == m) return ;
- LL ans1 = ;
- LL ans2 = ;
- LL mx = max(n - m, m); //这个也是必要的。能约就约最大的那个
- LL mi = n - mx;
- for (int i = ; i <= mi; ++i) {
- ans1 = ans1 * (mx + i) %MOD;
- ans2 = ans2 * i % MOD;
- }
- return (ans1 * quick_pow(ans2, MOD - , MOD) % MOD); //这里放到最后进行,不然会很慢
- }
- void work() {
- mp.clear();
- int n;
- scanf("%d", &n);
- for (int i = ; i <= n; ++i) {
- int x;
- scanf("%d", &x);
- int end = (int)sqrt(x + 0.5);
- for (int j = ; j <= end; ++j) {
- if (x % j == ) {
- mp[j]++;
- x /= j;
- while (x % j == ) {
- mp[j]++;
- x /= j;
- }
- end = (int)sqrt(x + 0.5);
- }
- }
- if (x != ) mp[x]++;
- }
- LL ans = ;
- for (map<int, int> :: iterator it = mp.begin(); it != mp.end(); ++it) {
- // cout << it->first << " " << it->second << endl;
- int val = it->second;
- // if (val > maxn) while(1);
- // ans *= C[val + n - 1][n - 1];
- ans *= C(val + n - , n - , MOD);
- ans %= MOD;
- }
- printf("%I64d\n", ans);
- }
- int main() {
- #ifdef local
- freopen("data.txt","r",stdin);
- #endif
- work();
- return ;
- }
C. On Number of Decompositions into Multipliers 组合数学的更多相关文章
- Codeforces396A - On Number of Decompositions into Multipliers
Portal Description 给出\(n(n\leq500)\)个\([1,10^9]\)的数,令\(m=\prod_{i=1}^n a_i\).求有多少个有序排列\(\{a_n\}\),使得 ...
- cf C On Number of Decompositions into Multipliers
题意:给你n个数,然后把这个n个数的乘积化成n个数相乘,可以化成多少个. 思路:分解质因数,求出每一个质因子的个数,然后用组合数学中隔板法把这些质因子分成n分,答案就是所有质因子划分成n份的情况的乘积 ...
- Codeforces Round #232 (Div. 1)
这次运气比较好,做出两题.本来是冲着第3题可以cdq分治做的,却没想出来,明天再想好了. A. On Number of Decompositions into Multipliers 题意:n个数a ...
- Codeforces Round #232 (Div. 1) A 解题报告
A. On Number of Decompositions into Multipliers 题目连接:http://codeforces.com/contest/396/problem/A 大意: ...
- Codeforces Round #232 (Div. 2) C
C. On Number of Decompositions into Multipliers time limit per test 1 second memory limit per test 2 ...
- POJ3252——Round Number(组合数学)
Round Numbers DescriptionThe cows, as you know, have no fingers or thumbs and thus are unable to pla ...
- poj 1019 Number Sequence 【组合数学+数字x的位宽函数】
题目地址:http://poj.org/problem?id=1019 Number Sequence Time Limit: 1000MS Memory Limit: 10000K Total ...
- poj3252-Round Number 组合数学
题目: Round Numbers Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8492 Accepted: 2963 ...
- 2019长安大学ACM校赛网络同步赛 J Binary Number(组合数学+贪心)
链接:https://ac.nowcoder.com/acm/contest/897/J 来源:牛客网 Binary Number 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32 ...
随机推荐
- codeforces A. Array 解题报告
题目链接:http://codeforces.com/problemset/problem/300/A 题目意思:给出n个数,将它们分成三批:1.所有数相乘的结果 < 0 2.所有数相乘的 ...
- Linux档案属性
输入命令:ls -al 档案类型权限: 第一個字元代表这个档案是『目录.档案或链接档等等』: 当为[ d ]则是目录: 当为[ - ]则是目录: 若是[ l ]则表示为链接档(link file): ...
- Constructing Roads In JGShining's Kingdom
点击打开题目链接 本题目是考察 最长递增子序列的 有n^2 n(logn) n^2 会超时的 下面两个方法的代码 思路 可以百度LIS LCS dp里面存子序列 n(logn) ...
- python之yield和Generator
首先我们从一个小程序导入,各定一个list,找出其中的素数,我们会这样写 import math def is_Prims(number): if number == 2: return True / ...
- POJ3061 Subsequence
Subsequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16520 Accepted: 7008 Desc ...
- POJ2217(最长公共子串)
Secretary Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 992 Accepted: 408 Descripti ...
- .NETFramework:Timers
ylbtech-.NETFramework:Timers 1.返回顶部 1. #region 程序集 System, Version=4.0.0.0, Culture=neutral, PublicK ...
- android项目源码
[置顶] Android精品开源项目整理_V20140221(持续更新中..) 让我们回顾下2013年有哪些精品资源:Android精品开源项目整理_V20131115(持续更新中..) 引言: ...
- socket辅助类
using System; using System.Collections; using System.Net; using System.Net.Sockets; using System.Tex ...
- linux之打包压缩命令
tar:主选项:[一条命令以下5个参数只能有一个]-c: --create 新建一个压缩文档,即打包-x: --extract,--get解压文件-t: --list,查看压缩文档里的文件目录-r:- ...