UVA10375 Choose and divide(唯一分解定理)

UVA - 10375 Choose and divide

Description

The binomial coefficient C(m, n) is defined as
C(m, n) = m!/((m − n)! n!)
Given four natural numbers p, q, r, and s, compute the the result of dividing C(p, q) by C(r, s).

Input

Input consists of a sequence of lines. Each line contains four non-negative integer numbers giving values for p, q, r, and s, respectively, separated by a single space. All the numbers will be smaller than 10,000 with p ≥ q and r ≥ s.

Output

For each line of input, print a single line containing a real number with 5 digits of precision in the fraction,
giving the number as described above. You may assume the result is not greater than 100,000,000.

Sample Input

10 5 14 9
93 45 84 59
145 95 143 92
995 487 996 488
2000 1000 1999 999
9998 4999 9996 4998

Sample Output

0.12587
505606.46055
1.28223
0.48996
2.00000
3.99960

题解

题意

已知C(m,n)=m! / (n!*(m-n!)),输入整数p,q,r,s(p>=q,r>=s,p,q,r,s<=10000),计算C(p,q)/C(r,s)。输出保证不超过10^8,保留5位小数

思路

唯一分解定理的题目,维护素数数组e,表示当前结果中唯一分解定理的各个素数的指数。然后最后对该指数进行计算即可。

代码

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;

#define REP(i,n) for(int i=0;i<(n);i++)

const int MAXN = 1e4+10;
int e[MAXN];
bool prime[MAXN];
vector<int> primes;

void pre(){
	for(int i = 2; i < MAXN; i ++) prime[i] = true;
    for(int i = 2; i*i < MAXN; i ++){
        if(prime[i]==true){
            for(int j = i*i; j < MAXN; j += i){
                prime[j] = false;  
            }
        }
    }
    for(int i=2;i<=MAXN;i++){
		if(prime[i]==true)	primes.push_back(i);
	}
}

void add_integer(int n,int d){
	for(int i=0;i<primes.size();i++){
		while(n%primes[i]==0){
			n/=primes[i];
			e[i]+=d;
		}
		if(n==1)	break;
	}
}

void add_factorial(int n,int d){
	for(int i=1;i<=n;i++)	add_integer(i,d);
}

int main(){
	pre();
	int p,q,r,s;
	while(~scanf("%d %d %d %d",&p,&q,&r,&s)){
		memset(e,0,sizeof(e));
		add_factorial(p,1);
		add_factorial(q,-1);
		add_factorial(p-q,-1);
		add_factorial(r,-1);
		add_factorial(s,1);
		add_factorial(r-s,1);
		double ans = 1;
		for(int i=0;i<primes.size();i++)
			ans *= pow(primes[i],e[i]);
		printf("%.5lf\n",ans);
	}
	return 0;
}

posted @ 2018-09-04 16:58  caomp  阅读(136)  评论(0)    收藏  举报