D. Same GCDs(欧拉函数)

D
题意:
给你两个整数 a a a m 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) gcd(a+x,m)=gcd(a,m)(0<=x<=m)成立 x x x的数量。
思路:
其实这道题目相比而言并不是很难,但是我却没有思路。
有一点我也没有注意,就是变量关系是 a < m aa<m
已知 a < m aa<m 0 < = x < = 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>=bgcd(a,b)=gcd(ab,b)

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

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

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

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

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

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

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

显然有 ( x ′ / d , m / d ) = 1 (x'/d,m/d)=1 (x/d,m/d)=1,故答案变成了在 [ 0 , m / d ) [0,m/d) [0,m/d)有多少数与 m / d m/d m/d互质,即 φ ( m / d ) \varphi(m/d) φ(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;
    }
}

你可能感兴趣的:(数论)