题解 CF983A 【Finite or not?】

囧仙

2020-08-29 23:01:33

Solution

## 题目大意 $T$ 组询问,每次询问 $\frac{n}{m}$ 在 $b$ 进制下是否为循环小数。 ## 题解 先将该分数化简为最简分数,即 $n,m$ 同时除以 $\gcd(n,m)$ 。此时有 $n,m$ 互质。 假定 $\frac{n}{m}$ 在 $b$ 进制下可以表示为有限小数。不妨设小数点后共有 $k$ 位。 于是,我们有: $$\frac{n\times b^k}{m} \in \Bbb N^* , \iff m \ | \ n\times b^k ,\iff m \ | \ b^k$$ 假设 $p$ 为 $m$ 的任意一个质因子。由于 $k$ 可以足够大,因此 $b$ 中至少应该含有一个 $p$ 。于是,问题转化为,$m$ 的每个质因子,都应该是 $b$ 的质因子。考虑如何求解。 由于 $m \le 10^{18}$ ,因此 $m$ 中每个质因子的次数不会超过 $60$ 。我们计算出 $b^{60}$ ,那么它对应质因子的次数必定不小于 $m$ 。于是,该分数可化为循环小数,当且仅当: $$b^{60} \equiv 0 \pmod m$$ 要注意的是,由于题目给出的数字较大,可能需要用快速乘法。 ## 参考代码 ```cpp #include<bits/stdc++.h> #pragma GCC optimize("Ofast") #define up(l,r,i) for(int i=l,END=r;i<=END;++i) #define dn(r,l,i) for(int i=r,END=l;i>=END;--i) using namespace std; typedef long long i64; const int INF =2147483647; i64 qread(){ i64 w=1,c,ret; while((c=getchar())> '9'||c< '0') w=(c=='-'?-1:1); ret=c-'0'; while((c=getchar())>='0'&&c<='9') ret=ret*10+c-'0'; return ret*w; } i64 mul(i64 x,i64 y,i64 p){ i64 r=0,t=x%p; while(y){ if(y&1) r+=t; t<<=1,y>>=1; if(t>=p) t-=p; if(r>=p) r-=p; } return r; } i64 pwr(i64 a,i64 b,i64 p){ i64 r=1,t=a; while(b){ if(b&1) r=mul(r,t,p); t=mul(t,t,p),b>>=1; } return r%p; } int main(){ dn(qread(),1,T){ i64 n=qread(),m=qread(),b=qread(),d=__gcd(n,m); n/=d,m/=d; puts(pwr(b,60,m)?"Infinite":"Finite"); } return 0; } ```