D. Same GCDs(欧拉函数)

D
题意:
给你两个整数 a a m m ,然后让你计算使 g c d ( a + x , m ) = g c d ( a , m ) ( 0 < = x < = m ) gcd(a+x,m)=gcd(a,m)(0<=x<=m) 成立 x x 的数量。
思路:
其实这道题目相比而言并不是很难,但是我却没有思路。
有一点我也没有注意,就是变量关系是 a < m a<m
已知 a < m a<m 0 < = x < = m 0<=x<=m
根据最大公约数的性质 a > = b g c d ( a , b ) = g c d ( a b , b ) a>=b,gcd(a,b)=gcd(a-b,b)

所以如果 a + x > = m a+x>=m

那么 ( a + x , m ) = ( a + x m , m ) (a+x,m)=(a+x-m,m)

a + x a+x 可以写成 ( a + x ) m o d    m (a+x)\mod m

我们令 x = ( a + x ) m o d    m x'=(a+x)\mod m      0 < = x < m \ \ \ \ 0<=x'<m

则有 ( x , m ) = ( a , m ) (x',m)=(a,m)

我们设 ( a , m ) = d (a,m)=d

( x , m ) = d (x',m)=d

显然有 ( x / d , m / d ) = 1 (x'/d,m/d)=1 ,故答案变成了在 [ 0 , m / d ) [0,m/d) 有多少数与 m / d m/d 互质,即 φ ( m / d ) \varphi(m/d)

const ll N = 1e5 + 10;
ll phi(ll x){
    ll ans = x;
    for(ll i = 2; i*i <= x; i++){
        if(x % i == 0){
            ans = ans / i * (i-1);
            while(x % i == 0) x /= i;
        }
    }
    if(x > 1) ans = ans / x * (x-1);
    return ans;
}
int main(){
    int t;
    cin >>t;
    while(t --){
        ll n,m;
        cin >>n >> m;
        ll d = __gcd(n,m);
        cout<<phi(m/d)<<endl;
    }
}
发布了589 篇原创文章 · 获赞 31 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_43408238/article/details/104128310
今日推荐