poj 2992 Divisors (素数打表+阶乘因子求解)
Divisors
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9617 | Accepted: 2821 |
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
1 /* 2 题意: 求 组合数 C(n,m)= n! / ( (n - m)! * m! ) 的 因数 个数,n<=431 3 4 设 n 的标准质因数分解式为 n = p1^a1 * p2^a2 *...* pk^ak , p1,p2..pk是素数 5 则 n 的 因数 个数 = (a1+1) * (a2+1) *...* (ak+1) 6 对于任意素数 p ,n!中有( n / p + n / p^2 + n / p^3 +...)个质因子 p 7 思路: 先打素数表,再对每个素数p求在C(n,m)的个数a,相乘即得结果 8 9 */ 10 11 /* 12 1. 13 C(n,m)= n! / ( (n - m)! * m! ) 枚举求解对于每一个素数因子。 14 居然可以这样。 15 ans=fun(n,prime[i])-fun(n-m,prime[i])-fun(m,prime[i]); 16 仔细想想,感觉..哈哈。 17 2.还有一点,要提。因为本人书写的习惯很差,所以经常在遇到要用__int64 的时候 18 就全部都用了。这题数据很好,就卡在这了好几处。超时... 19 其实在素数打表的过程中,我们也有体会,用bool的速度远远要小于标记用int的速度。 20 21 */ 22 23 #include<iostream> 24 #include<cstdio> 25 #include<cstring> 26 #include<cstdlib> 27 using namespace std; 28 29 30 bool s[434]; 31 int prime[300],len; 32 33 void make_prime() 34 { 35 int i,j; 36 for(i=1;i<=431;i++) 37 s[i]=false; 38 len=0; 39 40 for(i=2;i<=431;i++) 41 if(s[i]==false) 42 { 43 prime[++len]=i; 44 for(j=i*2;j<=431;j=j+i) 45 s[j]=true; 46 } 47 } 48 49 int fun(int n,int s) 50 { 51 int ans=0; 52 while(n) 53 { 54 n=n/s; 55 ans=ans+n; 56 } 57 return ans; 58 } 59 60 int main() 61 { 62 make_prime(); 63 int n,m,i,ans; 64 __int64 sum; 65 while(scanf("%d%d",&n,&m)>0) 66 { 67 sum=1; 68 for(i=1;i<=len;i++) 69 { 70 if(prime[i]>n)break; 71 ans=fun(n,prime[i])-fun(n-m,prime[i])-fun(m,prime[i]); 72 sum=sum*(ans+1); 73 } 74 printf("%I64d\n",sum); 75 } 76 return 0; 77 }