El blogger ha vuelto al artículo, este es el título de la primera función de Mobius.
Ideas
Preguntemos cuántos pares \ (x \ leq a, y \ leq b \) \ ((x, y) \) satisfar \ (\ gcd (x, y) = d \) es
equivalente a
cuántos \ ((x, y) \) satisface \ (x \ leq x / d, y \ leq b / d \) para que \ (\ gcd (x, y) = 1 \)
se establezca en \ (d (a, b , k) \) significa cuántos pares de \ ((x, y) \) satisfacen \ (x \ leq a, y \ leq b \) y \ (k | gcd (a, b) \)
Esta fórmula se puede optimizar dividiendo por bloques .
Deje que \ (f (a, b) \) indique cuántos pares \ ((x, y) \) satisfacen \ (x \ leq a, y \ leq b \) y \ (mcd (x, y) = 1 \)
Según el principio de tolerancia y exclusión
El significado aquí es probablemente que no hay restricciones en el número de duales como \ (d (a, b, 1) \) , y luego restando \ (mcd (x, y) \) es \ (2,3,5 ...... \ ) , El número de dobles en múltiplos, y luego vuelve a agregar \ (mcd (x, y) \) que es tanto \ (2 \) como múltiplos de \ (3 \) ...
\(código\)
/*
@ author:pyyyyyy
-----思路------
-----debug-------
memset(miu,1,sizeof(miu))不是把miu全赋值成1,我傻了
*/
#include<bits/stdc++.h>
using namespace std;
const int N=50041;
int T,a,b,d;
int miu[N],v[N];
void prime(int n)
{
for(int i=2;i<=n;++i)
{
if(v[i]) continue;
miu[i]=-1;
for(int j=2*i;j<=n;j+=i)
{
v[j]=1;
if((j/i)%i==0) miu[j]=0;
else miu[j]*=-1;
}
}
}
int Zap(){
a/=d,b/=d;
int ans=0;
if(a>b) swap(a,b);
for(int l=1,r;l<=a;l=r+1)
{
r=min(a/(a/l),b/(b/l));
ans+=(miu[r]-miu[l-1])*(a/l)*(b/l);
}
return ans;
}
int main()
{
for(int i=1;i<N;++i) miu[i]=1;
prime(N);
for(int i=1;i<N;++i) miu[i]+=miu[i-1];
cin>>T;
while(T--)
{
cin>>a>>b>>d;
cout<<Zap()<<'\n';
}
return 0;
}