题意:给定a,m,找a,m最大公约数与 a+x, m最大公约数相等的x的个数,大小不超过m
思路
首先分析
gcd(a, m) = gcd(a + x, m)
说明最大公约数d是上述所有数的约数,即x也是d的倍数,都除以d
则 a’ + x’ 与 m‘ 互质(因为除以最大的公约数),即问题变为在a’与m‘之间找与m’互质的数的个数,联想到欧拉函数
但是欧拉函数是从0或1开始找,找与n互质的数的个数
尝试变换,0-a’ 与 m’-a’+m’-1 两个区间 发现 gcd(x, y) = gcd(x- y, y) 即在两个区间内与m‘互质数为1的个数是相同的,变为求0-m’之间的与m‘的质数的个数
欧拉函数+gcd
实现
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
int t;
LL gcd(LL a, LL m)
{
return m?gcd(m, a % m): a;
}
LL get_euler(LL n)
{
LL ans = n;
for(int i = 2; i <= n / i; i ++)
{
if(n % i == 0)
{
ans = ans / i * (i - 1);
while(n % i == 0)
n /= i;
}
}
if(n > 1) ans = ans / n * (n - 1);
return ans;
}
int main()
{
cin >> t;
while(t --)
{
LL a, m;
cin >> a >> m;
LL d = gcd(a, m);
LL ans = get_euler(m / d);
cout << ans << endl;
}
return 0;
}