题目
给你n,列出所有以1~n作为分母的最简分数按照从小到大排序。
当n=1000000时,求在3/7左侧第一个数的分子
(这个问题的思考过程中顺便解决了求解在x/y左侧一共有多少个数字的问题)
题目链接:https://projecteuler.net/problem=71
题解
一开始题目看错了,看成了求3/7左侧一共有多少个数。
最简单的想法是,对于1~n找到每个数作为分母的时候,小于3/7的分子的取值范围是[1,m]
那么在这n个循环的过程中,每次都在求解[1,m]有多少个数与作为分母的数互质
根据莫比乌斯反演的思想,参考贾志鹏线性筛:
$$
\sum_{d|n} \mu (d) = [n=1] \\
\begin{aligned}
\sum_{i=1}^m{[gcd(i,n)=1]} & = \sum_{i=1}^m{\sum_{d|gcd(i,n)}{\mu (d)}} \\
& = \sum_{i=1}^m{\sum_{d|i \space and \space d|n}{\mu (d)}} \\
& = \sum_{d|n}{\sum_{i=1 \space and \space d|i}^{m}{\mu (d)}} \\
& = \sum_{d|n}{\left\lfloor m/d \right\rfloor \mu (d)}
\end{aligned}
$$
每次循环里的一次操作只要考虑约数即可,在$O(\sqrt n)$解决,这个代码就呼之欲出了。但并没有达到题目要求解的答案。对于题目要求的球左侧第一个数字,我们可以对于每个分母,求出小于当前数字3/7的和分母互质的最大分子,这个求的方法就是利用求互质数字的个数二分求解。
这样总的时间复杂度就是$O(n \sqrt n logn)$,所以运行时间达到了48s…代码如下:
|
|
但是这个做法显然太复杂又麻烦了,换个简单的方法就是,外层的n的循环对于每个分母都能找到一个最大的分子,无所谓他们是否互质,不互质就大家除以公约数即可,反正大小一定保证是最大的解。
|
|