题目给你 一个n和m 然后你要去求gcd(x,n)>=m的个数
保证1<=x<=m .
对于gcd(x,n)>=m可以看做是 gcd(x,n)=m,gcd(x,n)=m+1.....gcd(x,n)=n; m必为n的倍数
也就是 gcd(x/m,n/m)=1 也就是n/m内和n/m互质的数的个数。
只要计算范围内的因子值的欧拉函数即可
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn=1e5;
int n,prime[maxn],len=0;
int phi[maxn];
void makepri()
{
phi[1]=1;
for(int i=2;i<maxn;i++)
{
if(!phi[i])
{
prime[len++]=i;
for(int j=i;j<maxn;j+=i)
{
if(!phi[j]) phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
}
}
int euler(int a)
{
if(a==1) return 1;
int ans=a;
for(int i=0;i<len&&prime[i]<=a;i++)
{
if(a%prime[i]==0)
{
ans=ans/prime[i]*(prime[i]-1);
while(a%prime[i]==0) a/=prime[i];
}
}
if(a>1) ans=ans/a*(a-1);
return ans;
}
int main()
{
makepri();
int n;
scanf("%d",&n);
while(n--)
{
int a,b;
scanf("%d%d",&a,&b);
int en=sqrt(a),sum=0,k=a/b;
//printf("k=%d\n",k);
for(int i=1;i<=en&&i<=k;i++)
{
if(a%i==0)
{
if(i<maxn) sum+=phi[i];
else sum+=euler(i);
//printf(".%d.%d.%d\n",i,euler(i),sum);
if(i==a/i) continue;
if(a/i<=k)
{
if(a/i<maxn) sum+=phi[a/i];
else sum+=euler(a/i);
}
//printf("%d %d %d\n",a/i,euler(a/i),sum);
}
//printf("i:%d %d\n",i,sum);
}
printf("%d\n",sum);
}
return 0;
}