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

求一个数的因子个数 可以将它分解质因数分成若干个质数的幂的积,设他们的指数为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 但是p², 2*p²……这些数中有两个p    类似的p³ , 2*p³ , 3*p³ ……会有三个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
",ans[n][m]);
33     return 0;
34 }
原文地址:https://www.cnblogs.com/keximeiruguo/p/7811308.html