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 }

 

posted @ 2013-09-30 21:58  芷水  阅读(550)  评论(0编辑  收藏  举报