设m=C(n,k)=n!/((n-k)!*k!) 问题:求m的因数的个数
将m分解质因数得到
p1有a1个
p2有a2个
....
因为每一个质因数能够取0~ai个(所有取0就是1,所有取ai就是m)最后的答案就是(a1+1)*(a2+1)*....*
注意不能直接将m分解,由于太大,所以要先分解n,n-k,k,依据他们再来加减。
#include <iostream> #include <cstdio> #include <cmath> #include<cstring> #include<cstdlib> #include<vector> using namespace std; //C(n,k)=n!/((n-k)!*k!) struct node { int x,num; node(int a,int b){x=a;num=b;} }; vector<node> pri[444]; void init() { for(int i=1;i<=435;i++) { int tn=i; for(int j=2;j*j<=tn;j++) { int cnt=0; if(tn%j==0) { while(tn%j==0) {tn/=j;cnt++;} pri[i].push_back(node(j,cnt)); } } if(tn>1) pri[i].push_back(node(tn,1)); } } int pnum[444]; long long cal(int n,int k) { int tk=n-k; memset(pnum,0,sizeof(pnum)); for(int i=n;i>=1;i--) for(int j=0;j<pri[i].size();j++) pnum[pri[i][j].x]+=pri[i][j].num; for(int i=tk;i>=1;i--) for(int j=0;j<pri[i].size();j++) pnum[pri[i][j].x]-=pri[i][j].num; for(int i=k;i>=1;i--) for(int j=0;j<pri[i].size();j++) pnum[pri[i][j].x]-=pri[i][j].num; long long ans=1; for(int i=1;i<=n;i++) { if(pnum[i]) ans*=(pnum[i]+1); } return ans; } int main() { init(); int n,k; while(~scanf("%d%d",&n,&k)) { printf("%lld ",cal(n,k)); } return 0; }