解题报告: Codeforces 396A. On Number of Decompositions into Multipliers 组合
来源:互联网 发布:cygwin 运行linux程序 编辑:程序博客网 时间:2024/06/08 17:10
题目链接
题意:
给你n个数ai,m为这n个数的乘积,现在要把m重新拆分成n个有序数的乘积,问有多少种拆法。
思路:
第一步、对每个数进行拆分得到m的唯一分解式。
常用的拆数方法有:
①、直接对每个数x试除所有小于等于sqrt(x)的数
②、(常用)打出小于等于sqrt(x的最大取值)的素数表,然后试除小于等于sqrt(x)的素数。
比如对于这题的数据 ai<=1e9
如果使用方法一进行进行拆数,每个数最多需要试除sqrt(1e9)约3e4次
使用方法二进行拆数,我们先打出小于等于Sqrt(x)的素数表只有5200个,然后进行试除,效率大大提升
第二步、
分析题意可以认为是m有k个素数因子pi,每个因子有ai个
我们需要把这些因子放进n个位置中,当然每个位置上的可以什么也不放,这样代表这个位置的数为1。
可以进一步将问题分解为求每个素因子放的的方案数,结果就是每个素因子放的方案的乘积。
比如 对于m = 36 = 2^2 * 3^2的情况,对于 任一 素因子为2的放的方案 都能和 任一 素因子为3的放的方案 都能组成不同方案:
举个详细n=2的例子:
n=2表示有两个位置要放
那么素因子为2的方案有: ( 0 , 2 ) , ( 1 , 1 ) , ( 2 , 0) ,其对应的数就为 ( 1 , 4 ) , ( 2 , 2 ) , ( 4, 1)
那么素因子为3的方案有: ( 0 , 2 ) , ( 1 , 1 ) , ( 2 , 0) ,其对应的数就为 ( 1 , 9 ) , ( 3 , 3 ) , ( 9, 1)
可以发现每个素因子为2的方案和每个素因子为3的方案都能组成一个不同的新方案。
第三步、
现在问题就变成了将 ai 个数放进 n个位置,每个位置可以为空,但是ai个数必须放完。
这是一个经典的高中组合数学问题,可以用插板法得到答案就是C(n+ai-1,n)。
这样这道题就被完美解决了。
代码:
#include<bits/stdc++.h>const long long mod = 1e9+7;using namespace std;namespace prime_table{const int MAX_N = 1e5;int all=0;int pr[MAX_N/10+100];bool isp[MAX_N+10];long long fro[30005];long long ni[30005];inline long long qpow(long long x,long long y){ long long res =1; while(y){ if(y&1){ res = res * x %mod; }y>>=1; x = x * x % mod; }return res;}inline void init(){ fro[0]=ni[0]=1; for(int i=1;i<3e4;i++){ fro[i] = fro[i-1] * i %mod; ni[i] = qpow(fro[i],mod-2); } all = 0; memset(isp,0,sizeof(isp)); for(int i=2;i<=MAX_N;i++){ if(!isp[i]){ pr[all++] = i; }for(int j=0;j<all;j++){ long long t = 1LL*pr[j]*i ; if(t<=MAX_N){ isp[t] = true; if(i%pr[j]==0)break; }else { break; } } }return ;}}using namespace prime_table;long long C(int n,int m){ return fro[n]*ni[m]%mod*ni[n-m]%mod;}map<int,int>M;int main(){ init(); //return 0; int n; scanf("%d",&n); int x,sum=0; for(int t=1;t<=n;t++){ scanf("%d",&x); for(int i=0;i<all&&x>1;i++){ while(x%pr[i]==0){ x/=pr[i]; M[pr[i]]++; sum++; } }if(x>1)M[x]++,sum++; }long long ans = 1; //printf("%") for(auto it=M.begin();it!=M.end();it++){ int t = it->second; ans = ans * C(n+t-1,t) % mod; }printf("%I64d\n",ans); return 0;}
- 解题报告: Codeforces 396A. On Number of Decompositions into Multipliers 组合
- CF 396A On Number of Decompositions into Multipliers 解题报告(质因数分解+组合数计算)
- codeforces 396A A. On Number of Decompositions into Multipliers(组合数学+数论)
- Codeforces 396A On Number of Decompositions into Multipliers(组合数学)
- Codeforces-396A - On Number of Decompositions into Multipliers-组合计数
- CF 396A On Number of Decompositions into Multipliers
- CF 396A On Number of Decompositions into Multipliers
- CodeForce 396A On Number of Decompositions into Multipliers
- CF 396A On Number of Decompositions into Multipliers(组合数学)
- codeforces#232_div2_C On Number of Decompositions into Multipliers 数论 组合计数
- CodeForces 397C On Number of Decompositions into Multipliers(组合数学)
- 396AOn Number of Decompositions into Multipliers 组合
- Codeforces Round #232 (Div. 2) C. On Number of Decompositions into Multipliers 之我为何如此菜
- Letter Combinations of a Phone Number解题报告
- LeetCode解题报告--Letter Combinations of a Phone Number
- [leetcode] 17. Letter Combinations of a Phone Number 解题报告
- [LeetCode] Letter Combinations of a Phone Number 解题报告
- [Leetcode] 17. Letter Combinations of a Phone Number 解题报告
- servlet和Jsp生命周期解读
- 【PAT甲级】1078. Hashing (25)
- java-Exectors提供的四种基本线程池用法与比较详解
- Java 图片地址全部路径与相对路径替换
- SQL优化指南——优化工具使用
- 解题报告: Codeforces 396A. On Number of Decompositions into Multipliers 组合
- chrome开发者工具使用
- JS手机号正则验证
- 第8章 使用Spring Web Flow--概念学习
- windows 10 + vs2015+ opencv3.0.0 +附加模块opencv_contrib编译和配置
- Vue 2.0 高级实战-开发移动端音乐WebApp
- shell自动打包IPA
- Linux基础—源码安装软件
- Tensorflow学习之旅(十)——降噪自编码