F. GCD-GCD-GCD [ Problem 4045 ]
Description
给你两个数a,m;
问你在 [0,m − 1] 范围内有几个数 x 满足gcd(a,m) = gcd(a + x,m);
Input
第一行一个整数T;
接下来T行,每行两个整数a,m;
1 ≤ a < m ≤ 1e9
Output
针对每两个数,输出满足条件的x的数量。
Samples
Input Copy
3
4 9
5 10
42 9999999967
Output
6
1
9999999966
Hint
对于第一个4 9:
满足的x是:0 1 3 4 6 7
解题思路:
由更项减损术求最大公约数可知,若
x
>
y
,
则
有
g
c
d
(
x
,
y
)
=
g
c
d
(
x
−
y
,
y
)
x>y,则有gcd(x,y)=gcd(x-y,y)
x>y,则有gcd(x,y)=gcd(x−y,y)。
g
c
d
(
a
+
x
,
m
)
=
g
c
d
(
a
,
m
)
=
G
c
d
;
gcd(a+x,m)=gcd(a,m)=Gcd;
gcd(a+x,m)=gcd(a,m)=Gcd;
g
c
d
(
a
+
x
G
c
d
,
m
G
c
d
)
=
1
gcd(\frac{a+x}{Gcd},\frac{m}{Gcd})=1
gcd(Gcda+x,Gcdm)=1
当
a
+
x
<
m
时
,
即
求
[
a
G
c
d
,
m
G
c
d
)
中
与
m
G
c
d
互
质
的
个
数
;
当a+x < m时,即求[\frac{a}{Gcd},\frac{m}{Gcd})中与\frac{m}{Gcd}互质的个数;
当a+x<m时,即求[Gcda,Gcdm)中与Gcdm互质的个数;
当
a
+
x
≥
m
时
,
有
更
项
减
损
术
可
得
,
g
c
d
(
a
+
x
G
c
d
−
m
G
c
d
,
m
G
c
d
)
=
1
,
当a+x \geq m时,有更项减损术可得,gcd(\frac{a+x}{Gcd}-\frac{m}{Gcd},\frac{m}{Gcd})=1,
当a+x≥m时,有更项减损术可得,gcd(Gcda+x−Gcdm,Gcdm)=1,
即
求
[
0
,
a
G
c
d
)
中
与
m
G
c
d
互
质
的
个
数
;
即求[0,\frac{a}{Gcd})中与\frac{m}{Gcd}互质的个数;
即求[0,Gcda)中与Gcdm互质的个数;
取上述两种情况的并集可将该题转化为:求
m
G
c
d
\frac{m}{Gcd}
Gcdm 的欧拉函数即可。
上代码:
#pragma GCC optimize(2)
#pragma G++ optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll get_oula(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()
{
int t;
scanf("%d",&t);
while(t--)
{
ll a,m;
scanf("%lld%lld",&a,&m);
ll gcd = __gcd(a,m);
ll ans=get_oula(m/gcd);
cout << ans << endl;
}
return 0;
}