P3455 [POI2007]ZAP-Queries(莫比乌斯反演)

题目链接

给出 a,b,d,求满足 1≤xa,1≤yb,且 gcd(x,y)=d 的二元组 (x,y)的数量。

解法:莫比乌斯反演~

在这里插入图片描述

提出k来得到

在这里插入图片描述

使用莫比乌斯反演得到

在这里插入图片描述

之后将μ(d)提前得到

在这里插入图片描述

之后μ(d)与之后的求和公式无关,就可以直接进行求解,对于第一个求和公式的n为min(n/k,m/k)

在这里插入图片描述

之后就是简单的莫比乌斯筛和简单数论分块就能解决了

如果觉得讲的不够详细^ _ ^

推荐以下资料

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);
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值