有限小数

有限小数

给定三个整数 $p,q,b$,请你计算十进制表示下的 $p/q$ 的结果在 $b$ 进制下是否为有限小数。

输入格式

第一行包含整数 $T$,表示共有 $T$ 组测试数据。

每组数据占一行,包含三个整数 $p,q,b$。

输出格式

每组数据输出一行结果,如果 $p/q$ 的结果在 $b$ 进制下是有限小数,则输出 YES ,否则输出 NO 。

数据范围

前五个测试点满足 $1 \leq T \leq 10$。
所有测试点满足 $1 \leq T \leq {10}^{5}$,$0 \leq p \leq {10}^{18}$,$1 \leq q \leq {10}^{18}$,$2 \leq b \leq {10}^{18}$。

输入样例1:

2
6 12 10
4 3 10

输出样例1:

YES
NO

输入样例2:

4
1 1 2
9 36 2
4 12 3
3 5 4

输出样例2:

YES
YES
YES
NO

 

解题思路

  对于$\frac{p}{q}$,假设已经约分为最简分式,且只考虑小数的部分(即有$p < q$,如果$p > q$只需把整数部分去掉就可以),如果$\frac{p}{q}$在$b$进制下是一个有限小数,那么有${\left( {\frac{p}{q}} \right)}_b = 0.a_1a_2 \dots a_k$,在十进制下表示就是${\left( {\frac{p}{q}} \right)}_{10} = a_1 \cdot b^{-1} + a_2 \cdot b^{-2} + \dots + a_k \cdot b^{-k}$。现在令左右两式同时乘上$b^{k}$,得到$\left( {\frac{p}{q}} \right) \cdot b^{k} = a_1 \cdot b^{k-1} + a_2 \cdot b^{k-2} + \dots + a_k$,可以发现等式右边的$a_1 \cdot b^{k-1} + a_2 \cdot b^{k-2} + \dots + a_k$是一个整数,因此$\left( {\frac{p}{q}} \right) \cdot b^{k}$也是一个整数,又因为$\frac{p}{q}$已经是最简分式,因此有$q \mid b^{k}$。

  因此$\frac{p}{q}$在$b$进制下能用$k$位来表示有限小数$\Rightarrow$$q \mid b^{k}$。

  下面来推$\frac{p}{q}$在$b$进制下能用$k$位来表示有限小数$\Leftarrow$$q \mid b^{k}$。

  首先对于$a_1 \cdot b^{-1} + a_2 \cdot b^{-2} + \dots + a_k \cdot b^{-k}$,一定是一个小于$1$的数,这是以为$0 \leq a_i < b$,对$a_i$进行放缩,取$a_i = b-1$,有$$\begin{align*} a_1 \cdot b^{-1} + a_2 \cdot b^{-2} + \dots + a_k \cdot b^{-k} &\leq \left( {b-1} \right) \times \left( {b^{-1} + b^{-2} + \dots + b^{-k}} \right) \\ &= \left( {b-1} \right) \times \frac{1 - b^{-k}}{b-1} \\ &= 1 - b^{-k} < 1 \end{align*}$$

  现在令$\left( \frac{p}{q} \right) = a_1 \cdot b^{-1} + a_2 \cdot b^{-2} + \dots + a_k \cdot b^{-k}$左右两边乘以$b$,得到$\left( \frac{p}{q} \right) \cdot b = a_1 + a_2 \cdot b^{-1} + \dots + a_k \cdot b^{-k + 1}$,其中等式右边的$a_1$是一个整数,$a_2 \cdot b^{-1} + \dots + a_k \cdot b^{-k + 1}$是一个小于$1$的数,即得到$b$进制下的第$1$位数$a_1$。把$a_1$去掉,剩下的数继续乘上一个$b$,即可得到$b$进制下的第$2$位数$a_2$,以此类推,一共进行$k$次,就可以得到$k$位的$b$进制数,因为$q \mid b^{k}$,所有在等式左右两边乘以$b^k$后,等式右边得到的就只有一个整数而没有小数,意味着可以转换为有限的$b$进制数。因此有$\frac{p}{q}$在$b$进制下能用$k$位来表示有限小数$\Leftarrow$$q \mid b^{k}$。

  因此$\frac{p}{q}$在$b$进制下能用$k$位来表示有限小数$\Leftrightarrow$$q \mid b^{k}$。

  因此可以通过$q \mid b^{k}$来判断$p/q$在$b$进制下是否为有限小数。先将$p/q$约分,然后判断约分后的$q$的质因子是否包含在$b$的质因子内,这里如果用质因数分解会超时,因此需要用辗转相除法来判断,每次求$d = gcd \left( {q,b} \right)$,如果$d=1$而$q>1$说明$q \nmid b$,在$b$进制下为无限小数。然后还会卡常数,需要优化,即每次求出$d$后,需要一次性把$q$用$d$来除干净。

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 LL gcd(LL a, LL b) {
 7     return b ? gcd(b, a % b) : a;
 8 }
 9 
10 int main() {
11     int tot;
12     scanf("%d", &tot);
13     while (tot--) {
14         LL p, q, b;
15         scanf("%lld %lld %lld", &p, &q, &b);
16         q /= gcd(p, q);
17         
18         while (q > 1) {
19             LL d = gcd(q, b);
20             if (d == 1) break;
21             
22             // 如果直接q /= d; 会被卡常数
23             // 一次除干净
24             while (q % d == 0) {
25                 q /= d;
26             }
27         }
28         printf("%s\n", q == 1 ? "YES" : "NO");
29     }
30     
31     return 0;
32 }

 

参考资料

  AcWing 4484. 有限小数(AcWing杯 - 周赛):https://www.acwing.com/video/3978/

posted @ 2022-06-26 10:41  onlyblues  阅读(76)  评论(0编辑  收藏  举报
Web Analytics