Divisors

Posted SJY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Divisors相关的知识,希望对你有一定的参考价值。

Divisors
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 11186   Accepted: 3324

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

思路:先将421以内的素数打表,然后我们知道一个数可以分解成素数的乘积,N=p1k1+p2k2+...pnkn;
那么这个数的因子的个数就为(k1+1)(k2+1)(k3+1)....(kn+1);
我们知道组合数的公式为(n!)/(n-m)!/(m)!;所以我们算出分子分母的各个质因数的个数,然后上下一减就可以得到组合数的质因子。
关键是要先打出各个阶乘的素数表。
还有就是数据可能给重复的,所以询问一个记下到数组,还有组合数有对称性。
  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<stdlib.h>
  5 #include<string.h>
  6 #include<queue>
  7 #include<stack>
  8 #include<math.h>
  9 #include<vector>
 10 using namespace std;
 11 typedef long long LL;
 12 bool prime[1000]= {0};
 13 int ans[1000];
 14 int ak;
 15 int cnt[500][500]= {0};
 16 vector<int>vec[500];
 17 queue<int>que;
 18 int ask[500];
 19 LL aa[500][500]= {0};
 20 int cm[500][500];
 21 int main(void)
 22 {
 23         int i,j;
 24         ak=0;
 25         for(i=2; i<100; i++)
 26         {
 27                 if(!prime[i])
 28                 {
 29                         for(j=i; (i*j)<=431; j++)
 30                         {
 31                                 prime[i*j]=true;
 32                         }
 33                 }
 34         }
 35         for(i=2; i<=431; i++)
 36         {
 37                 if(!prime[i])
 38                 {
 39                         ans[ak++]=i;
 40                 }
 41         }
 42         for(i=2; i<=431; i++)
 43         {
 44                 int ss=i;
 45                 int vv=0;
 46                 int ff=0;
 47                 int cn=0;
 48                 while(ss>1)
 49                 {
 50                         if(ss%ans[vv]==0&&ff==0)
 51                         {
 52                                 que.push(ans[vv]);
 53                                 cn++;
 54                                 ff=1;
 55                                 ss/=ans[vv];
 56                         }
 57                         else if(ss%ans[vv]==0)
 58                         {
 59                                 cn++;
 60                                 ss/=ans[vv];
 61                         }
 62                         else if(ss%ans[vv])
 63                         {
 64                                 cnt[i][ans[vv]]=cn;
 65                                 vv++;
 66                                 cn=0;
 67                                 ff=0;
 68                         }
 69                 }
 70                 cnt[i][ans[vv]]+=cn;
 71                 while(!que.empty())
 72                 {
 73                         int cc=que.front();
 74                         que.pop();
 75                         vec[i].push_back(cc);
 76                 }
 77         }int ck;
 78         for(i=0;i<=431;i++)
 79         {
 80                for(j=0; j<vec[i].size(); j++)
 81                                 {
 82                                          ck=vec[i][j];
 83                                         cm[i][ck]+=cnt[i][ck];
 84                                 }
 85                                 if(i>=1)
 86                               for(j=0;j<ak;j++)
 87                                 {
 88                                     cm[i][ans[j]]+=cm[i-1][ans[j]];
 89                                 }
 90         }
 91         int n,m;
 92         while(scanf("%d %d",&n,&m)!=EOF)
 93         {
 94                 if(aa[n][m]!=0||aa[n][n-m]!=0)
 95                         printf("%lld\n",aa[n][m]);
 96                 else
 97                 {
 98                         memset(ask,0,sizeof(ask));
 99                         for(i=0;i<ak;i++)
100                         {
101                             ask[ans[i]]+=cm[n][ans[i]];
102                             ask[ans[i]]-=cm[m][ans[i]];
103                             ask[ans[i]]-=cm[n-m][ans[i]];
104                         }
105                         LL sum=1;
106                         for(i=0; i<ak; i++)
107                         {
108                                 sum*=(ask[ans[i]]+1);
109                         }
110                         printf("%lld\n",sum);
111                         aa[n][m]=sum;
112                         aa[n][n-m]=sum;
113                 }
114         }
115         return 0;
116 }

 

以上是关于Divisors的主要内容,如果未能解决你的问题,请参考以下文章

POJ-2992 Divisors(数学知识)