D. Same GCDs
题意:
给你两个整数a和m,然后使你计算使gcd(a+x,m) = gcd(a,m)(0<=x<=m,a<m )成立的x的数量。
思路:
已知a<m,0<=x<=m,
根据最大公约数的性质a>=b,gcd( a , b ) = gcd( a-b , b )
所以如果a+x>=m
那么gcd( a+x , m ) = gcd( a+x-m , m )
即a+x可以写成( a + x )mod m
我们令 x ′ = ( a + x ) mod m 0<=x′<=m
则有gcd( x′ , m ) = gcd(a,m)
我们设gcd( a , m )=d
则有gcd( x′ , m )=d,即gcd( x′ /d , m/d )=1。
故答案变成了在[ 0 ,m/d )有多少数与m/d互质,即求一个欧拉函数即可。
AC Code
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL a,m;
LL eular(LL n)
{
LL ans = n;
for(LL i=2; i*i <= n; ++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;
}
LL gcd(LL a,LL b)
{
if(b==0) return a;
return gcd(b,a%b);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&a,&m);
LL d=gcd(a,m);
printf("%lld\n",eular(m/d));
}
//system("pause");
return 0;
}