莫比乌斯反演例题

题目描述

给你正整数 a , b , c a,b,c a,b,c,求

∑ i = 1 a ∑ j = 1 b ∑ k = 1 c f ( i , j , k ) \sum\limits_{i=1}^a\sum\limits_{j=1}^b\sum\limits_{k=1}^cf(i,j,k) i=1aj=1bk=1cf(i,j,k)

其中 f f f函数的定义如下:

f ( i , j , k ) = { 1 gcd ⁡ ( i , j , k ) = 1 0 gcd ⁡ ( i , j , k ) ≠ 1 f(i,j,k)= \left\{\begin{matrix} 1\qquad \gcd(i,j,k)=1 \\ \\ 0\qquad \gcd(i,j,k)\neq 1 \end{matrix}\right. f(i,j,k)= 1gcd(i,j,k)=10gcd(i,j,k)=1

输出答案模 1 0 9 + 7 10^9+7 109+7后的值。


输入格式

一行三个正整数 a , b , c a,b,c a,b,c


输出格式

一行一个正整数,表示答案。


输入样例1

3 4 5

输出样例1

55

输入样例2

816 816 816

输出样例2

718333

数据范围

a × b × c ≤ 4 × 1 0 18 a\times b\times c\leq 4\times 10^{18} a×b×c4×1018


题解

前置知识:莫比乌斯反演

我们不妨设 a ≤ b ≤ c a\leq b\leq c abc,则显然 1 ≤ a ≤ 2 × 1 0 6 1\leq a\leq 2\times 10^6 1a2×106

题目即求

∑ i = 1 a ∑ j = 1 b ∑ k = 1 c [ gcd ⁡ ( i , j , k ) = = 1 ] \sum\limits_{i=1}^a\sum\limits_{j=1}^b\sum\limits_{k=1}^c[\gcd(i,j,k)==1] i=1aj=1bk=1c[gcd(i,j,k)==1]

利用莫比乌斯函数的性质,原式变为

∑ i = 1 a ∑ j = 1 b ∑ k = 1 c ∑ d ∣ i , d ∣ j , d ∣ k μ ( d ) \sum\limits_{i=1}^a\sum\limits_{j=1}^b\sum\limits_{k=1}^c\sum\limits_{d|i,d|j,d|k}\mu(d) i=1aj=1bk=1cdi,dj,dkμ(d)

枚举 d d d

∑ d = 1 a μ ( d ) × ⌊ a d ⌋ × ⌊ b d ⌋ × ⌊ c d ⌋ \sum\limits_{d=1}^a\mu(d)\times \lfloor\dfrac ad\rfloor\times \lfloor\dfrac bd\rfloor\times \lfloor\dfrac cd\rfloor d=1aμ(d)×da×db×dc

预处理出 μ \mu μ函数即可,时间复杂度为 O ( a ) O(a) O(a)


code

#include<bits/stdc++.h>
#define N 2000000
using namespace std;
int z[N+5],p[N+5],mu[N+5];
long long a,b,c,ans;
long long mod=1000000007;
void init(){
	mu[1]=1;
	for(int i=2;i<=N;i++){
		if(!z[i]){
			p[++p[0]]=i;mu[i]=-1;
		}
		for(int j=1;j<=p[0]&&i*p[j]<=N;j++){
			z[i*p[j]]=1;
			if(i%p[j]==0) break;
			mu[i*p[j]]=-mu[i];
		}
	}
}
int main()
{
	init();
	scanf("%lld%lld%lld",&a,&b,&c);
	if(b>c) swap(b,c);
	if(a>b) swap(a,b);
	if(b>c) swap(b,c);
	for(int i=1;i<=a;i++){
		ans=(ans+1ll*mu[i]*(a/i)%mod*(b/i)%mod*(c/i)%mod+mod)%mod;
	}
	printf("%lld",ans);
	return 0;
}
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值