Choose and divide UVA - 10375(筛素法+唯一分解定理的应用)
Posted cdplay
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Choose and divide UVA - 10375(筛素法+唯一分解定理的应用)相关的知识,希望对你有一定的参考价值。
通过题目给的定义C(m,n)=m!/(n!(m-n)!),以及题目要求计算的C(p,q)/C(r,s)联立可得
p!s!(r-s)!/q!r!(p-q)!
看到这个式子,我们可以分析一下,我们可以将每个阶乘,都通过唯一分解定理将它们分解
(具体教程可见:https://blog.csdn.net/qq_39439314/article/details/78270905)
所以,首先我们应该先求出10000以内的所有素数,然后通过唯一分解定理将各个阶乘都分解,求出所有存在的可用质数以及对应的质数的指数
p!s!(r-s)!/q!r!(p-q)!分母那一部分的阶乘分解时,对应质数增加时我们可以乘以一个-1,而分子对应的分解时,我们可以乘以一个1
最后再将所有的pow(质数,对应指数)相乘,得到相应的结果,结果保留五位小数。
1 #include<iostream>
2 #include<string.h>
3 #include <iomanip>
4 #include<cmath>
5
6 typedef long long ll;
7 const int maxn = 10000 + 10;
8
9 int primes[maxn];
10 bool p[maxn];
11 int e[maxn];
12 int tol = 0;
13
14 using namespace std;
15
16 void find_primes(int n);
17 void add_factorial(int n, int d);
18
19 int main()
20 {
21 ios::sync_with_stdio(false);
22 cin.tie(0);
23 cout.tie(0);
24
25 int p, q, r, s;
26 find_primes(maxn);//用筛素法打出素数表
27
28 while (cin >> p >> q >> r >> s)
29 {
30 memset(e, 0, sizeof(e));
31 add_factorial(p, 1);
32 add_factorial(s, 1);
33 add_factorial(r-s, 1);
34 add_factorial(q, -1);
35 add_factorial(r, -1);
36 add_factorial(p-q,-1);
37
38 double total = 1;
39
40 for (int i = 0; i < tol; i++)
41 total *= pow(primes[i], e[i]);
42 cout << fixed << setprecision(5) << total << endl;
43 }
44
45
46 return 0;
47 }
48
49 void find_primes(int n)//筛素法
50 {
51 memset(p, false, sizeof(p));
52
53 for (int i = 2; i <= n; i++)
54 {
55 if (!p[i])
56 {
57 primes[tol++] = i;
58 for (int j = i * i; j <= n; j += i)
59 p[j] = true;
60 }
61 }
62 }
63
64 void add_factorial(int n, int d)//唯一分解定理对n!质因数分解的应用
65 {
66 for (int i = 0; i < tol; i++)
67 {
68 if (primes[i] > n)
69 break;
70 ll t = primes[i];
71 while (t <= n)
72 {
73 e[i] += d * n / t;
74 t *= primes[i];
75 }
76 }
77 }
以上是关于Choose and divide UVA - 10375(筛素法+唯一分解定理的应用)的主要内容,如果未能解决你的问题,请参考以下文章