题目大意
有多组数据,每组有四个数,为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;
}