(Relax 数论1.16)POJ 2992 Divisors(C[N][K]中含素数的个数)

来源:互联网 发布:淘宝如何申请子账号 编辑:程序博客网 时间:2024/04/29 03:36

求组合数C(n, k)的约数的个数 (0 ≤ k ≤ n ≤ 431)

题目链接:http://poj.org/problem?id=2992

——>>3个公式:

  1、n!中含素数p的个数为n/p + n/p^2 + n/p^3 + ...(到0停)程序中通过cal函数实现

  2、C(n, k) = n! / (n-k)! / k!

  3、n = p1^a1*p2^a2*...*pk^ak约数的个数为(a1+1)(a2+1)...(ak+1)



#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>/** * 2 2 3 172 2 3 292 2 5 37 */using namespace std;int su[505];//这里不要开太大,否则会TLEbool u[505];int num = 0;int n;void prepare(){int i,j;memset(u,true,sizeof(u));for(i = 2 ; i <= 500 ;++i){if(u[i]){su[++num] = i;}for(j = 1 ; j <= 500 ; ++j ){if(i*su[j] >500){break;}u[i*su[j]] = false;if(i % su[j] ==0){break;}}}}int cal(int n,int pri){//n!含素数pri的个数return (n<pri)?0:(n/pri+cal(n/pri,pri));}int main(){prepare();int n,k;while(scanf("%d%d",&n,&k)!=EOF){long long sum = 1;int i;for(i = 1 ; i <= num ; ++i){//n! / (n-k)! / k!含素数的个数为:cal(n,su[i]) - cal(n-k,su[i]) - cal(k,su[i]) + 1sum *= (cal(n,su[i]) - cal(n-k,su[i]) - cal(k,su[i]) + 1);}printf("%lld\n",sum);}return 0;}


原创粉丝点击