Divisors
Time Limit: 1000MS | Memory Limit: 65536K | |
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 2
63 - 1.
Sample Input
5 1 6 3 10 4
Sample Output
2 6 16
题意:给你n和k,求C(K,N)(K<=N)的约数有多少个。
题解:先筛选出431之内的素数,然后对每个阶乘进行素因子分解,求组合数的素因子分解即可。
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; int main(){ bool boo[440]; int p[85],k=0; memset(boo,0,sizeof(boo)); boo[0]=boo[1]=0; for(i=2;i<440;i++){//素数 if(!boo[i])p[k++]=i; for(j=0;j<k&&i*p[j]<440;j++){ boo[i*p[j]]=1; if(!(i%p[j]))break; } } int jie[440][86],i,j,i1; memset(jie,0,sizeof(jie)); for(i=0;i<k;i++){ for(j=2;j<440;j++){//一个数包含素因子k的个数为 j/k 和 商中包含素因子k的个数 jie[j][i]=j/p[i]+jie[j/p[i]][i]; } } long long zu[432][432]; for(i=2;i<432;i++){ for(j=1;j<432;j++){ zu[i][j]=1; for(i1=0;i1<k&&jie[i][i1];i1++){//因子个数定理 int side=jie[i][i1]-jie[j][i1]-jie[i-j][i1]; if(side)zu[i][j]*=(side+1); } } } int n,x; while(scanf("%d%d",&n,&x)!=-1){ if(x==0||x==n){//C(N,N) C(0,N)都等于1 printf("1\n"); continue; } printf("%lld\n",zu[n][x]); } return 0; }