题目分析
本题求
1<=X<=N
与 N的gcd的值大于M的数的个数,这道题最初本来想用容斥原理去做,但是发现比较麻烦,因为还要保证gcd大于等于M,很不好求。于是还是要找到其他规律,我们可以先找到N的所有约数y,那么我们就会发现,我们只要求出(N/y)的欧拉函数,那么很明显任何与N/y互质的数L与y的乘积与N的最大公约数是y,那么我们求所有N的约数y,并找出大于等于M,然后求N/y的欧拉函数,把所有的加起来即可。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int Euler(int n){ //欧拉函数
int m = sqrt(n + 0.5);
int ans = n;
for(int i = 2; i <= m; 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,N,M;
scanf("%d", &T);
while(T--){
scanf("%d%d", &N, &M);
int len = sqrt(0.5 + N), ans = 0;
for(int i = 1; i <= len; i++){
if(N % i) continue;
if(i >= M && i != len) ans += Euler(N/i);
if((N / i) >= M) ans += Euler(i);
}
printf("%d\n", ans);
}
return 0;
}