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的主要内容,如果未能解决你的问题,请参考以下文章