uva10375(唯一分解定理)

来源:互联网 发布:php 随机昵称生成器 编辑:程序博客网 时间:2024/05/21 10:43

题目大意:

已知C(m,n)=m!/(n!*(m-n)!),现在给出p,q,r,s,求C(p,q)/C(r,s)。


题目分析:

因为数很大,直接算组合数,用long long也无法存下,但是每个数都是可以分解成若干个素数相乘的,我们没必要直接算出组合数的结果,直接拿分解出的素数来对应乘除就好了。


代码:

#include <vector>#include <string>#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;const LL maxn=10000+100;LL p,q,r,s;long long cnt[maxn];vector<LL>ans;vector<LL>num;vector<LL>prime;bool visit[maxn];void print_prime(){    for(LL i=0;i<(LL)prime.size();i++){        printf("%I64d ",prime[i]);    }    printf("\n");}void print_break(){    for(LL i=0;i<(LL)num.size();i++){        printf("%I64d %I64d\n",ans[i],num[i]);    }}void init(){    num.clear();prime.clear();    for(LL i=2;i<maxn;i++){        for(LL j=i*i;j<=maxn&&!visit[i];j+=i){            visit[j]=1;        }    }    for(LL i=2;i<=maxn;i++){        if(!visit[i]){            prime.push_back(i);        }    }}void Break(LL n,bool flag){    ans.clear();num.clear();    for(LL i=0;prime[i]<=n;i++){        LL cnt=0;        while(n%prime[i]==0){            cnt++;            n/=prime[i];        }        if(cnt){            ans.push_back(prime[i]);            num.push_back(cnt);        }    }    //print_break();    for(int i=0;i<(int)ans.size();i++){        LL val=ans[i];        if(flag){            cnt[val]+=num[i];        } else {            cnt[val]-=num[i];        }    }}LL poww(LL a,LL b){    LL ans=1;    while(b)    {        if(b&1)  ans*=a;        a*=a;        b>>=1;    }    return ans;}void solve_cycle(LL n,bool flag){    for(LL i=2;i<=n;i++){        Break(i,flag);    }}void solve(){    solve_cycle(p,true);solve_cycle(q,false);solve_cycle(p-q,false);    solve_cycle(r,false);solve_cycle(s,true);solve_cycle(r-s,true);    double sum=1;    for(int i=0;i<maxn;i++){        if(cnt[i]>0){            sum*=poww(i,cnt[i]);        } else if(cnt[i]<0){            sum/=poww(i,-cnt[i]);        }    }    printf("%.5lf\n",sum);}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    init();    //print_prime();    while(scanf("%I64d%I64d%I64d%I64d",&p,&q,&r,&s)!=EOF)    {        memset(cnt,0,sizeof(cnt));        solve();    }    return 0;}


原创粉丝点击