思路:
1.题意是给出和,让我们找出有多少个满足;
2.设和的最大公约数是,则我们可以将和表示成
且我们可以得知和互质且,因此我们需要求出在此时确定的情况下有多少个存在即可,即求的欧拉函数;
3.接着我们的目标就是求出对于每一个,与之对应的的欧拉函数,最后将它们相加即可;
4.可能有些人会有疑问(比如说我),题目问有多少种取值,我们就简单的遍历所有,将这些的欧拉函数相加就好了吗?不同的对应不同的,而同一个也对应许多不同的,有没有可能这些情况中,计算出来的值有重复?
答案是不会的。我们来证明一下,假设
则会有
则有,此时,因此必有的一个或多个质因子包含在中,这与互质相矛盾,因此的值不会重复;
代码:
#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()<<'
';
}
return 0;
}