The subject
This question is very obvious, directly use Mobius inversion to find gcd(x,y)=d.
You can set a function f(d) to represent the logarithm of gcd of d in 1~a and 1~b.
Then to learn a routine is to set a summation function F(d) to represent the logarithm of gcd of a multiple of d in 1~a and 1~b.
Obviously F(d)=f(d)+f(2d)+f(3d)...
Of course, F(d) can also be calculated by a formula =(a/d)*(b/d).
The next step is to see how the division is optimized in blocks, and specifically look at the code because I don't know how to express it in mathematical symbols. . emm
Code <don't mind if there are not many functions>
#include<cstdlib> #include<cstdio> #include<cstring> #include<iostream> using namespace std; int n; int d,a,b; int p[50010]; int miu[50010]; bool tf[50010]; int sum[50010]; long long solve(){ long long ans=0; int l = 1, r; a/=d;b/=d;//First divide a d, the problem is transformed into how many pairs of coprime logarithms are there from 1 to a and 1 to b while(l<=min(a,b)){//l enumerates the current accumulation to f(lx) r=min(a/(a/l),b/(b/l));//The division is divided into blocks to calculate the right endpoint. At this time, you can know the F(ix) between l~r (l<=i< =r) is the same value. ans=ans+(long long)(a/l)*(b/l)*(sum[r]-sum[l-1]);//So multiply the sum of miu values of this paragraph, you can use the prefix sum to calculate l=r+1; } return ans; } int main(){ scanf("%d",&n); miu[1]=1; sum[1]=1; for(int i=2;i<=50000;i++){//Linear sieve Möbius function if(!tf[i]) {miu[i]=-1;p[++p[0]]=i;} for(int j=1;j<=p[0] && (long long)i*p[j]<=50000;j++){ tf[p[j]*i]=true; if(i%p[j]==0) {miu[i*p[j]]=0;break;} miu[i*p[j]]=-miu[i]; } sum[i]=sum[i-1]+miu[i];//The prefix sum is calculated to facilitate the subsequent solution } while(n--){ scanf("%d %d %d",&a,&b,&d); printf("%lld\n",solve());//Enter the function to solve } }