CodeForces 396A 数论 组合数学
来源:互联网 发布:电工仿真软件 编辑:程序博客网 时间:2024/06/05 02:06
题目:http://codeforces.com/contest/396/problem/A
好久没做数论的东西了,一个获取素数的预处理跟素因子分解写错了,哭瞎了,呵呵,
首先ai最大值为10^9,n为500,最坏的情况 m最大值为500个10^9相乘,肯定不能获取m了,首选每一个ai肯定是m的一个因子,然后能分解就把ai给分解素因子,这样全部的ai都分解了 就能得到m的 所有素因子 以及 所有素因子的个数,题目求的 是n个因子的 不同序列的个数,所以每次 只能选出n个因子,这n个因子由素因子组成,其实就是对应每一个素因子 把它分配在n个位置上有多少种分法,然后所有素因子分法的 乘积就是最终的答案,至于怎么分配 其实就是隔板法
隔板法里有个是 允许有空的,这道题也是允许有空的
例1将20个大小形状完全相同的小球放入3个不同的盒子,允许有盒子为空,但球必须放完,有多少种不同的方法?
分析:本题中的小球大小形状完全相同,故这些小球没有区别,问题等价于将小球分成三组,允许有若干组无元素,用隔板法.
解析:将20个小球分成三组需要两块隔板,因为允许有盒子为空,不符合隔板法的原理,那就人为的再加上3个小球,保证每个盒子都至少分到一个小球,那就符合隔板法的要求了(分完后,再在每组中各去掉一个小球,即满足了题设的要求)。然后就变成待分小球总数为23个,球中间有22个空档,需要在这22个空档里加入2个隔板来分隔为3份,共有C(22,2)=231种不同的方法.
点评:对n件相同物品(或名额)分给m个人(或位置),允许若干个人(或位置)为空的问题,可以看成将这n件物品分成m组,允许若干组为空的问题.将n件物品分成m组,需要m-1块隔板,将这n件物品和m-1块隔板排成一排,占n+m-1位置,从这n+m-1个位置中选m-1个位置放隔板,因隔板无差别,故隔板之间无序,是组合问题,故隔板有Cn+m-1 m-1种不同的方法,再将物品放入其余位置,因物品相同无差别,故物品之间无顺序,是组合问题,只有1种放法,根据分步计数原理,共有Cn+m-1 m-1×1=Cn+m-1 m-1种排法
假设素因子p有 k个,那么分法就是 C[K + N - 1][N - 1],累积就可以了
const ll MOD = 1000000007;int n;map<int ,int > mp;map<int ,int > ::iterator it;const int MAXN = 15000;int C[MAXN + 1][500 + 1];//m最大大概为x * 10^4500左右,所以大概需要2^15000void Initial() {//组合数int i,j;for(i=0; i<=MAXN; i++) {if(i <= 500)C[0][i] = 0ll;C[i][0] = 1ll;}for(i=1; i<=MAXN; ++i) {for(j=1; j<=MAXN && j <= 500; j++)C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD;}}#define N 50009int prime[N];bool isprime[N];int nprime = 0;void make_prime() {//获取一定范围内素数memset(isprime,false,sizeof(isprime));for(int i=2;i<100005 ;i++)if(!isprime[i])for(int j=i*2;j<100005;j+=i)isprime[j]=true;for(int i=2;i<100005;i++)if(!isprime[i])prime[nprime++]=i;}void divide(int x) {//素因子分解 int temp = (int)sqrt(x * 1.0);for(int i=0;i < nprime;i++) {if(prime[i] > temp)break;while(x%prime[i] == 0) {mp[prime[i]]++;x /= prime[i];}}if(x != 1)mp[x]++;}void init() {mp.clear();}bool input() {while(scanf("%d",&n) == 1) {return false;}return true;}void cal() {for(int i=0;i<n;i++) {int x;scanf("%d",&x);divide(x);}int ans = 1;for(it = mp.begin();it != mp.end();it++) {int tmp = it->second;//int xx = C[tmp + n - 1][n - 1];//int yy = C[1][0];ans = (ans %MOD * C[tmp + n - 1][n - 1]%MOD)%MOD;}cout<<ans<<endl;}void output() {}int main() {Initial();make_prime();while(true) {init();if(input())return 0;cal();output();}return 0;}
0 0
- CodeForces 396A 数论 组合数学
- codeforces 396A A. On Number of Decompositions into Multipliers(组合数学+数论)
- Codeforces 223C Partial Sums 数论+组合数学
- 【1】【组合数学】CodeForces 650A Watchmen
- HDU 3944 组合数学+数论
- poj 3252 组合数学,数论
- HDU 4390 组合数学&数论
- 数论&&组合数学_模板
- Codeforces 396A On Number of Decompositions into Multipliers(组合数学)
- codeforces 553A Kyoya and Colored Balls 组合数学
- codeforces 553A Kyoya and Colored Balls(组合数学)
- 容斥 + 组合数学 ---Codeforces Round #317 A. Lengthening Sticks
- Kyoya and Colored Balls CodeForces 553A(组合数学)
- 【组合数学思维】CodeForces
- Codeforces Round #447 (Div. 2) B. Ralph And His Magic Field(数论,组合数学)
- poj2992数论与组合数学,略水。。。
- hdu 4790 数论 实现 组合数学
- BZOJ 2142 礼物 组合数学+数论
- Linux系统CentOS6的安装方法
- 二叉搜索树的非递归前中后序遍历 【微软面试100题 第四十三题】
- Hibernate对象的CRUD操作
- 把eclipse项目部署到tomcat插件上报配置文件找不到IOException的问题
- 客户端SMTP和POP3举例
- CodeForces 396A 数论 组合数学
- Android开发故障解决
- openstack, kvm, qemu-kvm以及libvirt之关系:
- coco2dx c++ 到 Lua 的具体解析
- 的人过得更高端
- 使用genext2fs制作ramdisk
- third day 自学测试
- 如何用键盘控制鼠标
- 08_01导航圆角背景1