浅谈莫比乌斯反演

浅谈莫比乌斯反演

简介( ch e ˇ  d a ˋ n \text{chě dàn} cheˇ daˋn):

莫比乌斯反演是数论中的重要内容。对于一些函数 ,如果很难直接求出它的值,而容易求出其倍数和或约数和 ,那么可以通过莫比乌斯反演简化运算,进行求值。

前置芝士:

引理 1 1 1 ∀ a , b , c ∈ Z , ⌊ a b c ⌋ = ⌊ ⌊ a b ⌋ c ⌋ \forall a,b,c \in Z, \lfloor \frac{a}{bc}\rfloor = \lfloor \frac{\lfloor \frac{a}{b} \rfloor}{c} \rfloor a,b,cZ,bca=cba
引理 2 2 2 ∀ n ∈ N + , ∣ { ⌊ n d ⌋ ∣ d ∈ N + , d ≤ n } ∣ ≤ ⌊ 2 n ⌋ \forall n \in N_+, \vert \{ \lfloor \frac{n}{d} \rfloor \vert d\in N_+,d\le n \}\vert \le \lfloor2\sqrt{n}\rfloor nN+,{dndN+,dn}2n

Tips: ∣ { } ∣ \vert\{\}\vert {}表示集合的长度,即集合中元素的个数。

1.整除分块:

用来求 ∑ ⌊ n i ⌋ \sum\lfloor\frac{n}{i}\rfloor in,直接模拟时间复杂度为 O ( n ) O(n) O(n),但是用整除分块可以优化到 O ( n ) O(\sqrt n) O(n )
对于 ∀ i ≤ n \forall i \le n in ,我们需要找到一个 i ≤ j m a x ≤ n i \le j_{max} \le n ijmaxn ,使得 ⌊ n i ⌋ = ⌊ n j m a x ⌋ \lfloor\frac{n}{i}\rfloor=\lfloor\frac{n}{j_{max}}\rfloor in=jmaxn
k=5
很容易发现: r = ⌊ n ⌊ n i ⌋ ⌋ r=\lfloor\frac{n}{\lfloor\frac{n}{i}\rfloor}\rfloor r=inn。(证明过程详见Oi-wiki

例题:
P2261 [CQOI2007]余数求和

题目描述:
给出正整数 n n n k k k,请计算 G ( n , k ) = ∑ i = 1 n k   m o d   i G(n, k) = \sum\limits_{i = 1}^n k \bmod i G(n,k)=i=1nkmodi
其中 k   m o d   i k\bmod i kmodi 表示 k k k 除以 i i i 的余数。

S o l u t i o n : \tt Solution: Solution:
一道非常基础的模板题,我们先来化简。
A n s = ∑ i = 1 n k   m o d   i Ans=\sum\limits_{i=1}^nk\bmod i Ans=i=1nkmodi
    = ∑ i = 1 n k − ⌊ k i ⌋ × i =\sum\limits_{i=1}^nk - \lfloor\frac{k}{i}\rfloor\times i =i=1nkik×i
    = n × k − ∑ i = 1 n ⌊ k i ⌋ × i =n\times k - \sum\limits_{i=1}^n\lfloor\frac{k}{i}\rfloor\times i =n×ki=1nik×i
然后就直接用整除分块做就行了
C o d e : \tt Code: Code:

#include <bits/stdc++.h>

using namespace std;

long long n, k, ans;

int main() {
	scanf("%lld%lld", &n, &k);
	ans = n * k;
	for (int l = 1, r; l <= n; l = r + 1) {
		if (k / l) r = min(k / (k / l), n);
		else r = n;
		ans -= (k / l) * (r - l + 1) * (l + r) / 2;
	}
	printf("%lld", ans);
	return 0;
}

2.狄利克雷卷积与数论函数

定义:
  • 数论函数: 值域为整数的函数。
  • 狄利克雷卷积: ( f ∗ g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) (f*g)(n)=\sum\limits_{d\vert n}f(d)g(\frac{n}{d}) (fg)(n)=dnf(d)g(dn)或者 ( f ∗ g ) ( n ) = ∑ x × y = n f ( x ) g ( y ) (f*g)(n)=\sum\limits_{x\times y =n}f(x)g(y) (fg)(n)=x×y=nf(x)g(y)
狄利克雷卷积的性质:
  • 交换律: f ∗ g = g ∗ f f*g=g*f fg=gf
  • 结合律: ( f ∗ g ) ∗ h = f ∗ ( g ∗ h ) (f*g)*h=f*(g*h) (fg)h=f(gh)
  • 分配律: f ∗ ( g + h ) = f ∗ g + f ∗ h f*(g+h)=f*g+f*h f(g+h)=fg+fh
  • f ∗ ε = f f*\varepsilon=f fε=f
积性函数:
定义:
  • 对于 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1,有 { f ( 1 ) = 1 f ( a b ) = f ( a ) × f ( b ) \begin{cases}f(1)=1\\f(ab)=f(a)\times f(b)\end{cases} {f(1)=1f(ab)=f(a)×f(b),则 f ( x ) f(x) f(x)被称为积性函数
  • 对于 ∀ a , b ∈ C \forall a,b \in C a,bC,有 { f ( 1 ) = 1 f ( a b ) = f ( a ) × f ( b ) \begin{cases}f(1)=1\\f(ab)=f(a)\times f(b)\end{cases} {f(1)=1f(ab)=f(a)×f(b),则 f ( x ) f(x) f(x)被称为完全积性函数
结论:
  • 两个积性函数的狄利克雷卷积还是积性函数
  • 积性函数还是积性函数
常见的积性函数:
  • 恒等函数: I ( n ) ≡ 1 \Iota(n) \equiv 1 I(n)1(无论 n n n是啥,恒等于1,废柴一个
  • 元函数: ε ( n ) = [ n = 1 ] \varepsilon(n)=[n=1] ε(n)=[n=1]
  • 单位函数: i d ( n ) = n id(n)=n id(n)=n
  • 莫比乌斯函数: μ ( x ) = { 0 ∃ d > 1 且 d 2 ∣ x ( − 1 ) k x = ∏ i = 1 k p i ( p i ∈ p r i m e ) \mu(x)=\begin{cases}0&\exists d>1且d^2|x\\(-1)^k&x=\prod\limits_{i=1}^kp_i(p_i\in {\tt prime})\end{cases} μ(x)=0(1)kd>1d2xx=i=1kpi(piprime)
    莫比乌斯函数的性质: μ ∗ I = ∑ d ∣ n μ ( d ) = [ n = 1 ] = ε \mu*\Iota=\sum\limits_{d|n}\mu(d)=[n=1]=\varepsilon μI=dnμ(d)=[n=1]=ε
    莫比乌斯函数的模板如下:
    void Mobius() {
        Mu[1] = 1;
        for (int i = 2; i <= Maxn; i++) {
     	    if (!vis[i]) Mu[i] = -1, p[++cnt] = i;
     	    for (int j = 1; j <= cnt && (int)i * p[j] <= Maxn; j++) {
     		    vis[i * p[j]] = true;
     		    if (i % p[j] == 0) break;
     		    Mu[i * p[j]] = -Mu[i];
     	    }
     	Mu[i] += Mu[i - 1];
        }
    }	
    

然后进入正题:

3.莫比乌斯反演

设两个数论函数 F ( x ) , f ( x ) F(x),f(x) F(x),f(x),则有:
{ F ( n ) = ∑ d ∣ n f ( d ) ① f ( n ) = ∑ d ∣ n μ ( d ) F ( n d ) ② f ( n ) = ∑ n ∣ d μ ( d n ) F ( d ) ③ \begin{cases}F(n)=\sum\limits_{d|n}f(d)&①\\f(n)=\sum\limits_{d|n}\mu(d)F(\frac{n}{d})&②\\f(n)=\sum\limits_{n|d}\mu(\frac{d}{n})F(d)&③\end{cases} F(n)=dnf(d)f(n)=dnμ(d)F(dn)f(n)=ndμ(nd)F(d)
证:
由①可得: F ∗ μ = f ∗ I ∗ μ F*\mu=f*\Iota*\mu Fμ=fIμ
由莫比乌斯函数的性质可得: F ∗ μ = f ∗ ε = f F*\mu=f*\varepsilon=f Fμ=fε=f
所以, f = μ ∗ F = ∑ d ∣ n μ ( d ) F ( n d ) f=\mu*F=\sum\limits_{d|n}\mu(d)F(\frac{n}{d}) f=μF=dnμ(d)F(dn)

例题:
P3455 [POI2007]ZAP-Queries

题目描述:

密码学家正在尝试破解一种叫 B S A BSA BSA 的密码。
他发现,在破解一条消息的同时,他还需要回答这样一种问题:
给出 a , b , d a,b,d a,b,d求满足 1 ≤ x ≤ a , 1 ≤ y ≤ b 1 \leq x \leq a,1 \leq y \leq b 1xa1yb,且 gcd ⁡ ( x , y ) = d \gcd(x,y)=d gcd(x,y)=d 的二元组 ( x , y ) (x,y) (x,y) 的数量。
因为要解决的问题实在太多了,他便过来寻求你的帮助。


输入格式:

输入第一行一个整数 n n n,代表要回答的问题个数。
接下来 n n n 行,每行三个整数 a , b , d a,b,d a,b,d


输出格式:

对于每组询问,输出一个整数代表答案。


在这里插入图片描述

S o l u t i o n : \tt Solution: Solution:
首先我们先把题意转换成人能看懂 的样子。
题目让我们求的东西:

∑ x = 1 a ∑ y = 1 b [ gcd ⁡ ( x , y ) = d ] \sum\limits_{x=1}^a\sum\limits_{y=1}^b{[\gcd(x,y)=d]} x=1ay=1b[gcd(x,y)=d]

我们先把 d d d提出来:

∑ x = 1 a d ∑ y = 1 b d [ gcd ⁡ ( x , y ) = 1 ] \sum\limits_{x=1}^{\frac{a}{d}}\sum\limits_{y=1}^{\frac{b}{d}}{[\gcd(x,y)=1]} x=1day=1db[gcd(x,y)=1]

很容易发现:

[ gcd ⁡ ( x , y ) = 1 ] = ∑ k ∣ gcd ⁡ ( x , y ) μ ( k ) [\gcd(x,y)=1]=\sum\limits_{k|\gcd(x,y)}\mu(k) [gcd(x,y)=1]=kgcd(x,y)μ(k)

然后,开始化简:

∑ x = 1 a d ∑ y = 1 b d ∑ k ∣ gcd ⁡ ( x , y ) μ ( k ) \sum\limits_{x=1}^{\frac{a}{d}}\sum\limits_{y=1}^{\frac{b}{d}}\sum\limits_{k|\gcd(x,y)}\mu(k) x=1day=1dbkgcd(x,y)μ(k)

拆掉 gcd ⁡ \gcd gcd,枚举k

∑ x = 1 a d ∑ y = 1 b d ∑ k = 1 min ⁡ ( a d , b d ) μ ( k ) [ k ∣ x ] [ k ∣ y ] \sum\limits_{x=1}^{\frac{a}{d}}\sum\limits_{y=1}^{\frac{b}{d}}\sum\limits_{k=1}^{\min(\frac{a}{d},\frac{b}{d})}\mu(k)[k|x][k|y] x=1day=1dbk=1min(da,db)μ(k)[kx][ky]

∑ k = 1 min ⁡ ( a d , b d ) μ ( k ) ∑ x = 1 a d [ k ∣ x ] ∑ y = 1 b d [ k ∣ y ] \sum\limits_{k=1}^{\min(\frac{a}{d},\frac{b}{d})}\mu(k)\sum\limits_{x=1}^{\frac{a}{d}}[k|x]\sum\limits_{y=1}^{\frac{b}{d}}[k|y] k=1min(da,db)μ(k)x=1da[kx]y=1db[ky]

∑ k = 1 min ⁡ ( a d , b d ) μ ( k ) ⌊ a d k ⌋ ⌊ b d k ⌋ \sum\limits_{k=1}^{\min(\frac{a}{d},\frac{b}{d})}\mu(k)\lfloor\frac{a}{dk}\rfloor\lfloor\frac{b}{dk}\rfloor k=1min(da,db)μ(k)dkadkb

很容易看出,最终结果就用莫比乌斯函数和数论分块计算就行了。

C o d e : \tt Code: Code:

#include <bits/stdc++.h>
#define int long long

using namespace std; 

int N, M, D, cnt;
int Mu[50005], vis[50005], p[50005];

void Mobius() {
	Mu[1] = 1;
	for (int i = 2; i <= 50005; i++) {
		if (!vis[i]) Mu[i] = -1, p[++cnt] = i;
		for (int j = 1; j <= cnt && (int)i * p[j] <= 50005; j++) {
			vis[i * p[j]] = true;
			if (i % p[j] == 0) break;
			Mu[i * p[j]] = -Mu[i];
		}
		Mu[i] += Mu[i - 1];
	}
}

void Solve() {
	int ans = 0;
	scanf("%lld%lld%lld", &N, &M, &D);
	if (N > M) swap(N, M);
	N /= D, M /= D;
	for (int l = 1, r; l <= N; l = r + 1) {
		r = min((M / (M / l)), (N / (N / l)));
		ans += (int)(Mu[r] - Mu[l - 1]) * (N / l) * (M / l);
	}
	printf("%lld\n", ans);
}

signed main() {
	Mobius();
	int T = 0;
	scanf("%lld", &T);
	while (T--) Solve();
	return 0;
}

P2257 YY的GCD

题目描述:

神犇 YY 虐完数论后给傻× kAc 出了一题
给定 N , M N, M N,M,求 1 ≤ x ≤ N 1 \leq x \leq N 1xN 1 ≤ y ≤ M 1 \leq y \leq M 1yM gcd ⁡ ( x , y ) \gcd(x, y) gcd(x,y) 为质数的 ( x , y ) (x, y) (x,y) 有多少对。


输入格式:

第一行一个整数 T T T 表述数据组数。
接下来 T T T 行,每行两个正整数, N , M N, M N,M


输出格式:

T T T 行,每行一个整数表示第 i i i 组数据的结果。


在这里插入图片描述
说明/提示:
T = 1 0 4 , N , M ≤ 1 0 7 T=10^4,N, M \leq 10^7 T=104N,M107

S o l u t i o n : \tt Solution: Solution:
这道题是前面那道题的升级版。
老规矩,我们先把题目化成人能看懂的样子:

∑ d ∈ p r i m e ∑ i = 1 x ∑ j = 1 y [ gcd ⁡ ( x , y ) = d ] \sum\limits_{d\in{\tt prime}}\sum\limits_{i=1}^x\sum\limits_{j=1}^y[\gcd(x,y)=d] dprimei=1xj=1y[gcd(x,y)=d]

根据套路,我们先把 d d d提出来:

∑ d ∈ p r i m e ∑ i = 1 x d ∑ j = 1 y d [ gcd ⁡ ( x , y ) = 1 ] \sum\limits_{d\in{\tt prime}}\sum\limits_{i=1}^{\frac{x}{d}}\sum\limits_{j=1}^{\frac{y}{d}}[\gcd(x,y)=1] dprimei=1dxj=1dy[gcd(x,y)=1]

然后转换成莫比乌斯函数的形式:

∑ d ∈ p r i m e ∑ i = 1 x d ∑ j = 1 y d ∑ k ∣ gcd ⁡ ( x , y ) μ ( k ) \sum\limits_{d\in {\tt prime}}\sum\limits_{i=1}^{\frac{x}{d}}\sum\limits_{j=1}^{\frac{y}{d}}\sum\limits_{k|\gcd(x,y)}\mu(k) dprimei=1dxj=1dykgcd(x,y)μ(k)

gcd ⁡ \gcd gcd提出来,枚举 k k k

∑ d ∈ p r i m e ∑ i = 1 x d ∑ j = 1 y d ∑ k = 1 min ⁡ ( x d , y d ) μ ( k ) [ k ∣ x ] [ k ∣ y ] \sum\limits_{d\in {\tt prime}}\sum\limits_{i=1}^{\frac{x}{d}}\sum\limits_{j=1}^{\frac{y}{d}}\sum\limits_{k=1}^{\min(\frac{x}{d},\frac{y}{d})}\mu(k)[k|x][k|y] dprimei=1dxj=1dyk=1min(dx,dy)μ(k)[kx][ky]

各回各家:

∑ d ∈ p r i m e ∑ k = 1 min ⁡ ( x d , y d ) μ ( k ) ∑ i = 1 x d [ k ∣ x ] ∑ j = 1 y d [ k ∣ y ] \sum\limits_{d\in {\tt prime}}\sum\limits_{k=1}^{\min(\frac{x}{d},\frac{y}{d})}\mu(k)\sum\limits_{i=1}^{\frac{x}{d}}[k|x]\sum\limits_{j=1}^{\frac{y}{d}} [k|y] dprimek=1min(dx,dy)μ(k)i=1dx[kx]j=1dy[ky]

后面的2个 Σ \Sigma Σ可以直接算:

∑ d ∈ p r i m e ∑ k = 1 min ⁡ ( x d , y d ) μ ( k ) ⌊ x d k ⌋ ⌊ y d k ⌋ \sum\limits_{d\in{\tt prime}}\sum\limits_{k=1}^{\min(\frac{x}{d},\frac{y}{d})}\mu(k)\lfloor\frac{x}{dk}\rfloor\lfloor\frac{y}{dk}\rfloor dprimek=1min(dx,dy)μ(k)dkxdky

枚举 d k dk dk T T T

∑ T = 1 min ⁡ ( x , y ) ⌊ x T ⌋ ⌊ y T ⌋ ∑ t ∣ T , t ∈ p r i m e μ ( T t ) \sum\limits_{T=1}^{\min(x,y)}\lfloor\frac{x}{T}\rfloor\lfloor\frac{y}{T}\rfloor\sum\limits_{t|T,t\in{\tt prime}}\mu(\frac{T}{t}) T=1min(x,y)TxTytT,tprimeμ(tT)

f ( x ) = ∑ p ∣ x , p ∈ p r i m e μ ( x p ) f(x)=\sum\limits_{p|x,p\in{\tt prime}}\mu(\frac{x}{p}) f(x)=px,pprimeμ(px)

x = i × y x =i\times y x=i×y y y y x x x的最小质因子。
①当 x ∈ p r i m e x\in {\tt prime} xprime时,很容易得到: f ( x ) = μ ( x x ) = μ ( 1 ) = 1 f(x)=\mu(\frac{x}{x})=\mu(1)=1 f(x)=μ(xx)=μ(1)=1
i m o d    y = 0 i\mod y=0 imody=0时,即 x x x存在多个最小质因子:

  • i i i没有多个相同的质因子时,有且只有 p = y p=y p=y μ ( x p ) = μ ( i ) ≠ 0 \mu(\frac{x}{p})=\mu(i)\neq0 μ(px)=μ(i)=0。因为当 p ≠ y p\neq y p=y时, ∃ y > 1 且 y 2 ∣ x \exists y>1且y^2\vert x y>1y2x
  • 根据莫比乌斯函数的性质,很容易知道:这时的函数值为 0 0 0,所以 f ( x ) = μ ( i ) f(x)=\mu(i) f(x)=μ(i)
  • i i i有多个相同的质因子时,对于任意 p p p,都有 μ ( x p ) = μ ( i ) = 0 \mu(\frac{x}{p})=\mu(i)=0 μ(px)=μ(i)=0
  • 所以当 i   m o d   y = 0 i\ mod\ y=0 i mod y=0时, f ( x ) = μ ( i ) f(x)=\mu(i) f(x)=μ(i)

i m o d    y ≠ 0 i\mod y \neq 0 imody=0时,即 x x x只存在一个最小质因子。

  • f ( i ) = ∑ p ∈ p r i m e , p ∣ i μ ( i p ) , f ( x ) = ∑ p ∈ p r i m e , p ∣ x μ ( i × y p ) f(i)=\sum\limits_{p \in {\tt prime}, p\vert i}\mu(\frac{i}{p}),f(x)=\sum\limits_{p \in {\tt prime}, p\vert x}\mu(\frac{i\times y}{p}) f(i)=pprime,piμ(pi),f(x)=pprime,pxμ(pi×y)
  • 根据 μ \mu μ线性筛的过程,很容易知道 μ ( i × y p ) = − μ ( i p ) \mu(\frac{i\times y}{p})=-\mu(\frac{i}{p}) μ(pi×y)=μ(pi),所以我们可以从 f ( x ) f(x) f(x)中找到任意一个属于 f ( i ) f(i) f(i)的项。
  • 因此 f ( x ) f(x) f(x) f ( i ) f(i) f(i)多了一项 μ ( i × y y ) = μ ( i ) \mu(\frac{i\times y}{y}) = \mu(i) μ(yi×y)=μ(i)
  • 所以当 i   m o d   y ≠ 0 i\ mod\ y\neq0 i mod y=0时, f ( x ) = − f ( i ) + μ ( i ) f(x)=-f(i)+\mu(i) f(x)=f(i)+μ(i)

综上所述,我们得出:
f ( x ) = { μ ( 1 ) = 1 , c a s e   1 : x ∈ p r i m e μ ( i ) , c a s e   2 : i m o d    y = 0. − f ( i ) + μ ( i ) , c a s e   3 : i m o d    y ≠ 0. f(x)=\begin{cases}\mu(1)=1,&case\ 1:x\in {\tt prime}\\\mu(i),&case\ 2:i\mod y=0.\\-f(i)+\mu(i),&case\ 3:i\mod y\neq0.\end{cases} f(x)=μ(1)=1,μ(i),f(i)+μ(i),case 1:xprimecase 2:imody=0.case 3:imody=0.
所以, A n s = ∑ T = 1 min ⁡ ( x , y ) ⌊ x T ⌋ ⌊ y T ⌋ f ( T ) Ans=\sum\limits_{T=1}^{\min(x,y)}\lfloor\frac{x}{T}\rfloor\lfloor\frac{y}{T}\rfloor f(T) Ans=T=1min(x,y)TxTyf(T)
我们只需要计算 f ( T ) f(T) f(T)的前缀和与数论分块就行了。
C o d e : Code: Code:

#include <bits/stdc++.h>
#define int unsigned long long

using namespace std;

const int Maxn = 1e7 + 5, lnMaxn = Maxn / 16;
int N, M, T, cnt;
int f[Maxn], Mu[Maxn], p[lnMaxn];
bool vis[Maxn];

void Mobius() {
	Mu[1] = vis[1] = 1;
	for (int i = 2; i < Maxn; i++) {
		if (!vis[i]) Mu[i] = -1, f[i] = 1, p[++cnt] = i;   //case 1
		for (int j = 1; j <= cnt && i * p[j] < Maxn; j++) {
			vis[i * p[j]] = true;
			if (i % p[j] == 0) {
				f[i * p[j]] = Mu[i];  //case 2
				break;
			}
			else {
				f[i * p[j]] = -f[i] + Mu[i];  //case 3
			}
			Mu[i * p[j]] = -Mu[i];
		}
		f[i] += f[i - 1]; 
	}
}

void Solve() {
	int ans = 0;
	scanf("%llu%llu", &N, &M);
	if (N > M) swap(N, M);
	for (int l = 1, r; l <= N; l = r + 1) {
		r = min(N / (N / l), (M / (M / l)));
		ans += (f[r] - f[l - 1]) * (N / l) * (M / l);
	}
	printf("%llu\n", ans);
}

signed main() {
	scanf("%llu", &T);
	Mobius();
	while (T--) Solve();
	return 0;
} 

P3327 [SDOI2015]约数个数和

题目描述:

d ( x ) d(x) d(x) x x x 的约数个数,给定 n , m n,m n,m,求 ∑ i = 1 n ∑ j = 1 m d ( i j ) \sum\limits_{i=1}^n\sum\limits_{j=1}^md(ij) i=1nj=1md(ij).

输入格式:

输入文件包含多组测试数据。
第一行,一个整数 T T T,表示测试数据的组数。
接下来的 T T T 行,每行两个整数 n , m n,m n,m

输出格式:

T 行,每行一个整数,表示你所求的答案。

样例
说明/提示:
对于 100 % 100\% 100%的数据, 1 ≤ T , n , m ≤ 50000 1\le T,n,m \le 50000 1T,n,m50000

S o l u t i o n : \tt Solution: Solution:
首先我们得知道一个公式: d ( i j ) = ∑ x ∣ i ∑ y ∣ j [ gcd ⁡ ( x , y ) = 1 ] d(ij)=\sum\limits_{x\vert i}\sum\limits_{y\vert j}[\gcd(x,y)=1] d(ij)=xiyj[gcd(x,y)=1]

然后进行化简:

∑ i = 1 n ∑ j = 1 m ∑ x ∣ i ∑ y ∣ j [ gcd ⁡ ( x , y ) = 1 ] \sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{x\vert i}\sum\limits_{y\vert j}[\gcd(x,y)=1] i=1nj=1mxiyj[gcd(x,y)=1]

枚举 gcd ⁡ ( x , y ) \gcd(x,y) gcd(x,y)的因数:

∑ i = 1 n ∑ j = 1 m ∑ x ∣ i ∑ y ∣ j ∑ d ∣ gcd ⁡ ( x , y ) μ ( d ) \sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{x\vert i}\sum\limits_{y\vert j}\sum\limits_{d\vert\gcd(x,y)}\mu(d) i=1nj=1mxiyjdgcd(x,y)μ(d)
∑ i = 1 n ∑ j = 1 m ∑ x ∣ i ∑ y ∣ j ∑ d = 1 min ⁡ ( n , m ) μ ( d ) [ d ∣ gcd ⁡ ( x , y ) ] \sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{x\vert i}\sum\limits_{y\vert j}\sum\limits_{d=1}^{\min(n,m)}\mu(d)[d\vert\gcd(x,y)] i=1nj=1mxiyjd=1min(n,m)μ(d)[dgcd(x,y)]

把莫比乌斯函数提到前面:

∑ d = 1 min ⁡ ( n , m ) μ ( d ) ∑ i = 1 n ∑ j = 1 m ∑ x ∣ i ∑ y ∣ j [ d ∣ gcd ⁡ ( x , y ) ] \sum\limits_{d=1}^{\min(n,m)}\mu(d)\sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{x\vert i}\sum\limits_{y\vert j}[d\vert\gcd(x,y)] d=1min(n,m)μ(d)i=1nj=1mxiyj[dgcd(x,y)]

把枚举 i , j i,j i,j的因子,改成枚举 x , y x,y x,y

∑ d = 1 min ⁡ ( n , m ) μ ( d ) ∑ x = 1 n ∑ y = 1 m [ d ∣ gcd ⁡ ( x , y ) ] ⌊ n x ⌋ ⌊ n y ⌋ \sum\limits_{d=1}^{\min(n,m)}\mu(d)\sum\limits_{x=1}^n\sum\limits_{y=1}^m[d\vert\gcd(x,y)]\lfloor\frac{n}{x}\rfloor\lfloor\frac{n}{y}\rfloor d=1min(n,m)μ(d)x=1ny=1m[dgcd(x,y)]xnyn

d d d提出来,这样 gcd ⁡ ( x , y ) \gcd(x,y) gcd(x,y)就可以消去了:

∑ d = 1 min ⁡ ( n , m ) μ ( d ) ∑ x = 1 n d ∑ y = 1 m d ⌊ n d x ⌋ ⌊ m d y ⌋ \sum\limits_{d=1}^{\min(n,m)}\mu(d)\sum\limits_{x=1}^{\frac{n}{d}}\sum\limits_{y=1}^{\frac{m}{d}}\lfloor\frac{n}{dx}\rfloor\lfloor\frac{m}{dy}\rfloor d=1min(n,m)μ(d)x=1dny=1dmdxndym

然后整理一下:

∑ d = 1 min ⁡ ( n , m ) μ ( d ) ∑ x = 1 ⌊ n d ⌋ ⌊ n d x ⌋ ∑ y = 1 m d ⌊ ⌊ m d ⌋ y ⌋ \sum\limits_{d=1}^{\min(n,m)}\mu(d)\sum\limits_{x=1}^{\lfloor\frac{n}{d}\rfloor}\lfloor\frac{\frac{n}{d}}{x}\rfloor\sum\limits_{y=1}^{\frac{m}{d}}\lfloor\frac{\lfloor\frac{m}{d}\rfloor}{y}\rfloor d=1min(n,m)μ(d)x=1dnxdny=1dmydm

令:

f ( x ) = ∑ i = 1 x ⌊ x i ⌋ f(x)=\sum\limits_{i=1}^{x}\lfloor\frac{x}{i}\rfloor f(x)=i=1xix

很容易发现:

f ( ⌊ n d ⌋ ) = ∑ x = 1 ⌊ n d ⌋ ⌊ ⌊ n d ⌋ x ⌋   f ( ⌊ m d ⌋ ) = ∑ x = 1 ⌊ m d ⌋ ⌊ ⌊ m d ⌋ x ⌋ f(\lfloor\frac{n}{d}\rfloor)=\sum\limits_{x=1}^{\lfloor\frac{n}{d}\rfloor}\lfloor\frac{\lfloor\frac{n}{d}\rfloor}{x}\rfloor \\\ f(\lfloor\frac{m}{d}\rfloor)=\sum\limits_{x=1}^{\lfloor\frac{m}{d}\rfloor}\lfloor\frac{\lfloor\frac{m}{d}\rfloor}{x}\rfloor f(dn)=x=1dnxdn f(dm)=x=1dmxdm

所以:

A n s = ∑ d = 1 min ⁡ ( n , m ) μ ( d ) ∗ f ( ⌊ n d ⌋ ) ∗ f ( ⌊ m d ⌋ ) Ans=\sum\limits_{d=1}^{\min(n,m)}\mu(d)*f(\lfloor\frac{n}{d}\rfloor)*f(\lfloor\frac{m}{d}\rfloor) Ans=d=1min(n,m)μ(d)f(dn)f(dm)

我们只需要处理出 μ ( d ) \mu(d) μ(d)的前缀和与 f ( x ) f(x) f(x)就行了。

C o d e : \tt Code: Code:

#include <bits/stdc++.h>
#define int long long

using namespace std;

int T, N, M;
int p[500100], Mu[500100], f[500100];
bool vis[500100];

void Mobius() {
	Mu[1] = vis[1] = 1;
	for (int i = 2; i <= 5e4; i++) {  //处理μ(d)的前缀和
		if (!vis[i]) Mu[i] = -1, p[++p[0]] = i;
		for (int j = 1; j <= p[0] && i * p[j] <= 5e4; j++) {
			vis[i * p[j]] = true;
			if (i % p[j] == 0) break;
			Mu[i * p[j]] = -Mu[i];
		}
		Mu[i] += Mu[i - 1];
	}
	for (int i = 1; i <= 5e4; i++)  //处理f(x)
		for (int l = 1, r; l <= i; l = r + 1)  {
			r = i / (i / l);
			f[i] += (r - l + 1) * (i / l);
		}
}

void Solve() {
	int ans = 0;
	scanf("%lld%lld", &N, &M);
	if (N > M) swap(N, M);
	for (int l = 1, r; l <= N; l = r + 1) {
		r = min(N / (N / l), M / (M / l));
		ans += (Mu[r] - Mu[l - 1]) * f[N / l] * f[M / l];
	}
	printf("%lld\n", ans);
}

signed main() {
	scanf("%lld", &T);
	Mobius();
	while (T--) Solve();
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值