题目大意
给两个数(a)和(m,a<m),找出所有的(x),满足(0leq x<m)并且(gcd(a,m)=gcd(a+x,m))。
解题思路
题目中的(a<m)十分重要。如果(a+x > m),(gcd(a+x-m,m)=gcd(a+x,m)),又因为题目中(0leq x<m),所以实际上(a+x)的值等价于(a+x mod m)的值所以((a+xin [0,m-1))。那么这样问题就转换成了满足求(gcd(k,m)=gcd(a,m),kin [0,m-1))中的(k)的数量,显然,如果等式成立的话(k)一定能被(gcd(a,m))整除,也就是求满足(gcd(kdiv gcd(a,m), mdiv gcd(a,m)) = 1)的(k)的数量。换句话说也就是求所有小于(m)的数中与(mdiv gcd(a,m))互质的数的数量也就是(gcd(a,m))的欧拉函数。
代码
ll eular(ll num) {
ll res = num;
for (ll i = 2; i*i<=num; ++i)
if (num%i==0) {
while(num%i==0) num/=i;
res = res/i*(i-1);
}
if (num>1) res = res/num*(num-1);
return res;
}
int main(void) {
int t; cin >> t;
while(t--) {
ll a, m; cin >> a >> m;
ll ans = eular(m/__gcd(a,m));
cout << ans << endl;
}
return 0;
}