题目链接
给出 a,b,d,求满足 1≤x≤a,1≤y≤b,且 gcd(x,y)=d 的二元组 (x,y)的数量。
解法:莫比乌斯反演~
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/41aed6297deab0b8e8f05e14164d6aa1.png#pic_center)
提出k来得到
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ae4a41a18fc3bbeebea02a487ed49244.png#pic_center)
使用莫比乌斯反演得到
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5f9d7935b91a0dba5893b59c1d9cbaa0.png#pic_center)
之后将μ(d)提前得到
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9562fdd4aaccfb732a27b73033a53081.png#pic_center)
之后μ(d)与之后的求和公式无关,就可以直接进行求解,对于第一个求和公式的n为min(n/k,m/k)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ec18421b4e4cfee2d675c2859405a22c.png#pic_center)
之后就是简单的莫比乌斯筛和简单数论分块就能解决了
如果觉得讲的不够详细^ _ ^
推荐以下资料
https://www.luogu.com.cn/problem/solution/P3455
https://oi-wiki.org/math/number-theory/mobius/
#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
#define x first
#define y second
using namespace std;
const int maxn = 5e4 + 100;
ll mu[maxn];
int vis[maxn];
int prime[maxn];
int tot;
int sum[maxn];
void init(){
mu[1] = 1;
for(int i = 2; i < maxn; i++){
if(!vis[i])mu[i] = -1,prime[++tot] = i;
for(int j = 1; j <= tot && prime[j]*i<maxn; j++){
vis[i*prime[j]] = 1;
if(i % prime[j] == 0){
mu[i * prime[j]] = 0;
break;
}
mu[i * prime[j]] = -mu[i];
}
}
for(int i = 1; i < maxn; i++){
mu[i] += mu[i - 1];
}
}
int main(){
init();
int t;
scanf("%d",&t);
while(t--){
int a,b,d;
scanf("%d%d%d",&a,&b,&d);
ll n = a/d,m = b/d;
ll ans = 0;
for(ll l = 1,r; l <= min(n,m); l = r + 1){
r = min(n/(n/l),m/(m/l));
ans += (mu[r] - mu[l - 1])*(n/l)*(m/l);
}
printf("%lld\n",ans);
}
}