题解 UVA10375 【Choose and divide】题解

题目大意

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


猜你喜欢

转载自blog.csdn.net/sjzezwzy/article/details/80208880