思路:
1.题意是给出
n
n
n和
m
m
m,让我们找出有多少个
x
(
1
<
=
x
<
=
n
)
x(1<=x<=n)
x(1<=x<=n)满足
g
c
d
(
n
,
x
)
>
=
m
gcd(n,x)>=m
gcd(n,x)>=m;
2.设
n
n
n和
x
x
x的最大公约数是
d
d
d,则我们可以将
n
n
n和
x
x
x表示成
{
n
=
p
∗
d
x
=
q
∗
d
\begin{cases} n=p*d\\ x=q*d \end{cases}
{n=p∗dx=q∗d
且我们可以得知
p
p
p和
q
q
q互质且
q
<
=
p
q<=p
q<=p,因此我们需要求出在此时
d
d
d确定的情况下有多少个
q
q
q存在即可,即求
p
p
p的欧拉函数;
3.接着我们的目标就是求出对于每一个
d
(
d
>
=
m
)
d(d>=m)
d(d>=m),与之对应的
p
p
p的欧拉函数,最后将它们相加即可;
4.可能有些人会有疑问(比如说我),题目问
x
x
x有多少种取值,我们就简单的遍历所有
p
p
p,将这些
p
p
p的欧拉函数相加就好了吗?不同的
d
d
d对应不同的
p
p
p,而同一个
p
p
p也对应许多不同的
q
q
q,有没有可能这些情况中,计算出来的
x
x
x值有重复?
答案是不会的。我们来证明一下,假设
{
n
=
p
1
∗
d
1
x
1
=
q
1
∗
d
1
n
=
p
2
∗
d
2
x
2
=
q
2
∗
d
2
x
1
=
x
2
\begin{cases} n=p1*d1\\ x1=q1*d1\\ n=p2*d2\\ x2=q2*d2\\ x1=x2 \end{cases}
⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧n=p1∗d1x1=q1∗d1n=p2∗d2x2=q2∗d2x1=x2
则会有
{
p
1
∗
d
1
=
p
2
∗
d
2
q
1
∗
d
1
=
q
2
∗
d
2
\begin{cases} p1*d1=p2*d2\\ q1*d1=q2*d2 \end{cases}
{p1∗d1=p2∗d2q1∗d1=q2∗d2
则有
p
1
=
p
2
∗
q
1
q
2
p1=\frac{p2*q1}{q2}
p1=q2p2∗q1,此时
q
1
≠
q
2
q1\neq q2
q1=q2,因此必有
q
1
q1
q1的一个或多个质因子包含在
p
1
p1
p1中,这与
q
1
p
1
q1p1
q1p1互质相矛盾,因此
x
x
x的值不会重复;
代码:
#include<iostream>
#include<vector>
using namespace std;
int n,m;
vector<int> v;
void cal_divisor(int n){ //which is greater than m or equals to m
for(int i=1;i*i<=n;i++) if(n%i==0){
if(i>=m) v.push_back(i);
if(i!=n/i&&n/i>=m) v.push_back(n/i);
}
}
int eular(int n){
int ans=n;
for(int i=2;i*i<=n;i++) if(n%i==0){
ans-=ans/i;
while(n%i==0) n/=i;
}
if(n>1) ans-=ans/n;
return ans;
}
int solve(){
if(m==1) return n;
v.clear();
cal_divisor(n);
int ans=0;
for(auto x:v) ans+=eular(n/x);
return ans;
}
int main(){
int t; cin>>t;
while(t--){
cin>>n>>m;
cout<<solve()<<'\n';
}
return 0;
}