1. 程式人生 > >poj2992 階乘分解

poj2992 階乘分解

/*
將C(n,k)質因數分解,然後約束個數按公式計算 
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long 

int v[1000],prime[1000],m,c[200],p[200];
void init(int n){
    memset(prime,0,sizeof prime);
    memset(v,0,sizeof v);
    m=0;
    for(int i=2;i<=n;i++){
        
if(v[i]==0){ v[i]=i; prime[++m]=i; } for(int j=1;j<=m;j++){ if(prime[j]>v[i] || prime[j]*i>n) break; v[i*prime[j]]=prime[j]; } } } int cal(int p,int n){ int ret=0,tmp=p; while(tmp<=n){ ret+=n/tmp; tmp
*=p; } return ret; } int main(){ int n,k; init(500); while(scanf("%d%d",&n,&k)==2){ memset(c,0,sizeof c); memset(p,0,sizeof p); ll ans=1; for(int i=1;i<=m;i++){ if(prime[i]>n) break; c[i]+=cal(prime[i],n); }
for(int i=1;i<=m;i++){ if(prime[i]>n-k)break; c[i]-=cal(prime[i],n-k); } for(int i=1;i<=m;i++){ if(prime[i]>k) break; c[i]-=cal(prime[i],k); } for(int i=1;i<=m;i++) if(c[i]) ans*=(c[i]+1); printf("%lld\n",ans); } }