【Codeforces Round #483 (Div. 2) C】Finite or not?

时间:2023-03-10 05:32:00
【Codeforces Round #483 (Div. 2)  C】Finite or not?

【链接】 我是链接,点我呀:)

【题意】

在这里输入题意

【题解】

有个性质。
如果p/q是分数的最简形式。
那么p/q能化成有限小数。
当且仅当q的质因数分解形式中只有质因子2和5
(且不能出现其他质因子)
(也就是说q的质因子只能出现10的质因子里面出现过的
因为只有这样分母才能化成10^n的形式。
才能化成小数。

因此。对于在b进制下的小数p/q

只要看看q的质因子是不是都是b的质因子就可以了。

显然可以用gcd来搞。

每次都用q去除gcd(q,b)

这样。如果最后q能够变成1.那就说明q的质因子都是b的质因子。

(gcd本质上就是两个数相同质因子中取指数较小的那个,然后全都乘起来。

但不要每次都重新获取q,b的gcd.

用上次的结果尝试继续除就好。

因为可能出现q>b的情况,这种情况上一轮的__gcd(q,b)可能可以继续除q

如果不加这个优化。过不了。

虽然这个除的过程最多循环64次。

但是还有__gcd(x,y)的复杂度在里面。

会超时。

【代码】

#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define pll pair<ll,ll>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep1(i,a,b) for(int i=a;i>=b;i--)
#define rson rt<<1|1,m+1,r
#define lson rt<<1,l,m
using namespace std; ll p,q,b; void solve(){
cin >> p >> q >> b;
if (p==0) {
cout<<"Finite"<<endl;
return;
}
long long temp = __gcd(p,q);
p/=temp;
q/=temp;
if (q==1) {
cout<<"Finite"<<endl;
return;
}
while(__gcd(q,b)>1){
ll temp = __gcd(q,b);
while (q%temp==0) q/=temp;
}
if (q==1){
cout<<"Finite"<<endl;
}else{
cout<<"Infinite"<<endl;
}
} int main()
{
#ifdef LOCAL_DEFINE
freopen("D:\\rush.txt","r",stdin);
#endif
ios::sync_with_stdio(false),cin.tie(0);
int T;
cin >> T;
while (T--){
solve();
}
return 0;
}