Codeforces 1295D Same GCDs(欧拉函数)
题目大意
给两个数\(a\)和\(m,a<m\),找出所有的\(x\),满足\(0\leq x<m\)并且\(gcd(a,m)=gcd(a+x,m)\)。
解题思路
题目中的\(a<m\)十分重要。如果\(a+x > m\),\(gcd(a+x-m,m)=gcd(a+x,m)\),又因为题目中\(0\leq x<m\),所以实际上\(a+x\)的值等价于\(a+x \mod m\)的值所以\((a+x\in [0,m-1)\)。那么这样问题就转换成了满足求\(gcd(k,m)=gcd(a,m),k\in [0,m-1)\)中的\(k\)的数量,显然,如果等式成立的话\(k\)一定能被\(gcd(a,m)\)整除,也就是求满足\(gcd(k\div gcd(a,m), m\div gcd(a,m)) = 1\)的\(k\)的数量。换句话说也就是求所有小于\(m\)的数中与\(m\div 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;
}