题目大意
有多组数据,每组有四个数,为p,q,r,s,求C(p,q)/C(r,s)。C(m,n)=m!/(n!*(m-n)!)。
解析
裸的唯一分解定理,可预先将1至10000的因数处理好,然后开数组对因数个数进行维护,最后进行乘或除即可,时间大约为10ms。
#include<bits/stdc++.h> using namespace std; int al[10001],v[10000],prime[3500],m=0; int pd(int n){ memset(prime,0,sizeof(prime)); memset(v,0,sizeof(v)); for(int i=2;i<=n;i++){ if(!v[i]){ v[i]=i; prime[++m]=i; } for(int j=1;j<=m;j++){ if(prime[j]>v[i]||prime[j]>n/i) break; v[i*prime[j]]=prime[j]; } } } void cl1(int a){ for(int i=2;i<=a;i++){ if(i==v[i]){ al[i]++; continue; } int j=i; while(j!=v[j]){ al[v[j]]++; j/=v[j]; } al[j]++; } } void cl2(int a){ for(int i=2;i<=a;i++){ if(i==v[i]){ al[i]--; continue; } int j=i; while(j!=v[j]){ al[v[j]]--; j/=v[j]; } al[j]--; } } int main(){ pd(10000); int p,q,r,s; while(cin>>p>>q>>r>>s){ memset(al,0,sizeof(al)); cl1(p); cl1(s); cl1(r-s); cl2(q); cl2(r); cl2(p-q); double ans=1; for(int i=1;i<=10000;i++){ if(!al[i]) continue; ans*=pow(i,al[i]); } printf("%.5lf\n",ans); } return 0; }