您的位置:首页 > 其它

Uva10375 Choose and divide(数论、唯一分解定理、快速幂)

2016-08-13 10:11 369 查看
Uva10375 Choose and divide(数论、唯一分解定理、快速幂)

链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1316

题目

Time Limit:3000MS     Memory Limit:0KB


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(p, q)除C(r, s)的结果

分析

如果暴力算肯定超时,我们可以思考一下怎样简化相除的过程:通过唯一分界定理,记录每个因子的数量,可以认为是进行上下约分操作,最后只需要对各个因子进行相除即可。

源码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<string>
#include<sstream>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<utility>
#include<sstream>
#define mem0(x) memset(x,0,sizeof x)
#define mem1(x) memset(x,-1,sizeof x)
#define dbug cout<<"here"<<endl;
//#define LOCAL

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6+10;
const int MOD = 1000000007;

ull p,q,r,s;
ll cnt[10010];

ull quickPow(ull a, ull b){
ull ans = 1;
while(b){
if(b & 1){
ans = ans*a;
}
b = b >> 1;
a = a*a;
}
return ans;
}

void division(ull a, int type){
int up = sqrt(a+1);
for(int i = 2; i < up; ++i){
if(a%i == 0){
while(a%i == 0){
a /= i;
cnt[i] += type;
}
}
if(a == 1)
break;
}
if(a>1)
cnt[a] += type;
}

void addElement(ull n){
for(int i = 1; i <= n; ++i){
division(i, 1);
}
}

void incElement(ull n){
for(int i = 1; i <= n; ++i){
division(i, -1);
}
}

void
4000
solve(){
double ans = 1;
for(int i = 1; i <= 10000; ++i){
if(cnt[i]>0){
ans *= quickPow(i, cnt[i]);
}
else if (cnt[i]<0){
ans /= quickPow(i, abs(cnt[i]));
}
}
printf("%.5lf\n",ans);
}

int main(){
#ifdef LOCAL
freopen("C:\\Users\\asus-z\\Desktop\\input.txt","r",stdin);
freopen("C:\\Users\\asus-z\\Desktop\\output.txt","w",stdout);
#endif
while(cin >> p >> q >> r >> s){
mem0(cnt);
addElement(p);
addElement(r-s);
addElement(s);
incElement(r);
incElement(p-q);
incElement(q);
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: