POJ-2992 Divisors(数学知识)

Divisors

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 12085   Accepted: 3600

Description

Your task in this problem is to determine the number of divisors of Cnk. Just for fun -- or do you need any special reason for such a useful computation?

Input

The input consists of several instances. Each instance consists of a single line containing two integers n and k (0 ≤ k ≤ n ≤ 431), separated by a single space.

Output

For each instance, output a line containing exactly one integer -- the number of distinct divisors of Cnk. For the input instances, this number does not exceed 263 - 1.

Sample Input

5 1
6 3
10 4

Sample Output

2
6
16

Source

CTU Open 2005

求一个数的因子个数 可以将它分解质因数分成若干个质数的幂的积,设他们的指数为a1,a2,a3……an 则这个数的因子个数为(a1+1)*(a2+1)*(a3+1)*……*(an+1)  当求a!中出现的多少个p的时候 a!可以表示成1*2*3*……*(p-1)*p*(p+1)*……*(2*p-1)*(2*p)*(2*p+1)*……其中p, 2*p , 3*p……会有因子p所以先加上a/p 但是p2, 2*p2……这些数中有两个p    类似的p3 , 2*p3 , 3*p3 ……会有三个p  所以在处理的时候要考虑全 具体看代码

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 typedef long long LL;
 4 const int MAX=435;
 5 int n,m,len,pri[MAX];LL ans[MAX][MAX];
 6 bool t[MAX];
 7 void prime(){
 8     register int i,j;
 9     memset(t,true,sizeof(t));
10     for (i=2;i<MAX;i++){
11         if (t[i]) pri[++len]=i;
12         for (j=1;j<=len && pri[j]*i<MAX;j++) {t[pri[j]*i]=false; if (i%pri[j]==0) break;}
13     }
14 }
15 inline int calc(register int x,register int y){
16     register int an=0;
17     while (x){an+=x/y;x/=y;}
18     return an;
19 }
20 int main(){
21     freopen ("divisors.in","r",stdin);freopen ("divisors.out","w",stdout);
22     register int i,j,k;
23     prime();ans[0][0]=1;
24     for (i=1;i<MAX;i++){
25         ans[i][i]=ans[i][0]=1;
26         for (j=1;j<i;j++){
27             ans[i][j]=1;
28             for (k=1;k<=len;k++)
29                 ans[i][j]*=calc(i,pri[k])-calc(j,pri[k])-calc(i-j,pri[k])+1;
30         }
31     }
32     while (~scanf("%d%d",&n,&m)) printf("%lld\n",ans[n][m]);
33     return 0;
34 }
时间: 2024-08-30 06:08:05

POJ-2992 Divisors(数学知识)的相关文章

poj 2992 Divisors 整数分解

设m=C(n,k)=n!/((n-k)!*k!) 问题:求m的因数的个数 将m分解质因数得到 p1有a1个 p2有a2个 .... 由于每个质因数可以取0~ai个(全部取0就是1,全部取ai就是m)最后的答案就是(a1+1)*(a2+1)*....* 注意不能直接将m分解,因为太大,所以要先分解n,n-k,k,根据他们再来加减. #include <iostream> #include <cstdio> #include <cmath> #include<cstr

POJ 2992 Divisors 求组合数因子个数

题目来源:POJ 2992 Divisors 题意:... 思路:素数分解的唯一性 一个数可以被分解成若干素数相乘 p1^x1*p2^x2*...*pn^xn 根据乘法原理 因子数为 (x1+1)*(x2+1)*...*(xn+1) 不能直接求出组合数 会溢出 也不能把每个乘的数分解因子 这样会超时 C(N,M)=N!/(M!*(N-M)!) 另dp[i][j] 代表为i的阶乘中j因子的个数(j是素数) 那么i素数的个数为dp[n][i]-dp[m][i]-dp[n-m][i] 最后for循环从

poj 2992 Divisors

题目链接:http://poj.org/problem?id=2992 题目大意:就是叫你求组合数C(n,m)的因子的个数. 思路:求解这题需要用到以下几个定理 1.对任意的n,可以这么表示 n=p1^e1*p2^e2*p3*e3*......pn^en .(p1,p2,p3......pn都为素数) 2.对任意的n的因子数为:(1+e1)*(1+e2)*(1+e3)*......*(1+en) 3.n!的素数因子=(n-1)!的素数因子+n的素数因子 4.C(n,k)的素因子=n!的素因子 -

组合数学+整数分解 POJ 2992 Divisors

题意:给n,k,求C(n,k)的约数的个数. 由于C(n,k)=n!/(k!*(n-k)!),所以只要分别把分子分母的素因子的次数求出来,再用分子的每个素因子的次数减去分母的每个素因子的次数就可以得到C(n,k)的素数分解式,约数个数就等于(p1+1)(p2+1)*...*(pn+1).这道题n,k的范围都是四百多,按理说O(N^2)的算法可以过的,但是测试数据太多了,暴力的方法会TLE.看别人的报告知道了求N!的某个素因子次数的递归算法,然后枚举每个素数,求出它在阶乘中的次数,就可以AC了.

canvas绘图数学知识总结

题外话: 最近看了一本书叫 <HTML5 Canvas核心技术 图形.动画与游戏开发>已经算是看了85%,基本接近尾声,所以近期会多总结一些关于canvas的东西, 这本书讲的还算可以,最大的障碍就是一些数学知识和理论的应用,第八章的碰撞检测比较难理解,看这部分的时候,我感觉非常吃力,向量运算是主要技术点, 我这本书是以阅读源码为主的,有兴趣的朋友可以看看,大家交流一下. 三角函数 canvas中所有和角有关的api 都是用的弧度 js api 如 Math.sin(),Math.cos,Ma

ACM数学知识体系

#include<iostream> #include<string> #include<stack> using namespace std; #define n 8 stack <int *> s; int * createMaze(){//初始化迷宫 int i,j; int * a; a=new int[n*n]; for(i=0;i<n;i++){ for(j=0;j<n;j++){ *(a+n*i+j)=-1;//不设置为0的原因是超

编程需要知道多少数学知识?

数学和编程有一种容易让人误解的联系.许多人认为在开始学习编程之前必须对数学很在行或者数学分数很高.但一个人为了编程的话,需要学习多少数学呢? ([伯乐在线编注]:本文仅为 Al Sweigart 一家之言,再推荐 Alan Skorkin 的这篇文章<数学是成就卓越开发人员的必备技能>.) 实际上不需要很多.这篇文章中我会深入探讨编程中所需要的数学知识.你可能已经都知道了. 对于基本的编程,你需要知道下面的: 加减乘除 - 实际上,电脑会帮你作加减乘除运算.你仅需要知道什么时候运用它们. 模运

【Cocos2D学习】Lua——数学知识的基本应用

学习Cocox,真的是相当麻烦,IDE的支持太差了,Cocox的各种版本也是多种多样,我先研究的是用Lua语言开发,但是学习起来还是蛮有趣的,我喜欢这种学习.下面基本的数学知识在Cocox的几种应用: 1.跳动的小球(向量的应用) local direction=cc.p(math.random(-1,1),math.random(-1,1)) cc.pNormalize(direction) local dot=display.newDrawNode():addTo(self):center(

关于一部分数学知识》(工具向)(实时更新)

这里汇总一下关于联赛的一些数学知识,以后做到有些关于数学的题就可以较快的解决(和愉快的装13). 1.组合数 这个应该是高中数学就学过的知识,在这里详细的介绍就不给出了,可以自行百度. 公式一: 这个比较好理解,在备选的n个里面找一个一定不选,那么我们就一定要在其他n-1个备选数里找出m个数字,所以有c(n-1,m),但如果一定要选刚才没有选的那一个,就要去掉这个,从剩下的n-1个里面取m-1个,所以有c(n-1.m-1):对于每一个m这样做结果是重复且一样的,所以得出Pascal公式. 公式二