原题链接:3999. 最大公约数 - AcWing题库

题意:给定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;
}