UVa--10375 Choose and divide(math)

来源:互联网 发布:数据质量整改报告 编辑:程序博客网 时间:2024/05/22 03:04

UVa 10375

题解

C(p,q)C(r,s)=p!(rs)!s!q!(pq)!r!

根据算术基本定理:n=pa11pa22...pakk,其中pk为素数,aiN+.
n!=12...n,将n!从1到n进行上述分解,用一个数组e表示分解后的各个素数的指数。例如:e=(1,2,1,0,0,0...)表示213251,因此,还需要事先计算10000内的素数。

#include <bits/stdc++.h>using namespace std;const int maxn = 10000;vector<int> primes;bool a[maxn];int  e[maxn];void genePrime(){    for(int i = 2; i < maxn; ++i)    {        if(a[i]) continue;        primes.push_back(i);        for(int j = i * i; j < maxn; j += i)            a[j] = true;        /*for(int j = 2; i * j <= maxn; ++j)            a[i * j] = true;*/    }    /*for(size_t i = 0; i < primes.size(); ++i)        cout << primes[i] << ' ';*/}void add_fac(int n, int d){    for(int i = 1; i <= n; ++i)     //calculate n!    {        int k = i;        for(int j = 0; j < primes.size(); ++j)        {            while(k % primes[j] == 0)            {                k /= primes[j];                e[j] += d;            }            if(k == 1) break;        }    }}int main(){    #ifdef LOCAL    freopen("data.in", "r", stdin);    #endif // LOCAL    int p, q, r, s;    genePrime();    while(cin >> p >> q >> r >> s)    {        memset(e, 0, sizeof(e));        add_fac(p, 1);        add_fac(q, -1);        add_fac(p - q, -1);        add_fac(r, -1);        add_fac(s, 1);        add_fac(r - s, 1);        double ans = 1;        for(int i = 0; i < primes.size(); ++i)            ans *= pow(primes[i], e[i]);        printf("%.5f\n", ans);    }    return 0;}

其中,add_fac(n, d)表示乘以 (n!)d.

0 0