【算法&题解】莫比乌斯反演及一些经典套路

本文介绍了莫比乌斯函数及其反演的基本概念,通过经典套路展示了如何利用莫比乌斯反演解决求(i,j)=x的个数、(i,j)为质数的个数以及约数个数和的问题。通过巧妙的数学转换和除法分块优化,实现了高效算法,并给出了相关例题。" 6191987,66847,《狂人C》精华与争议解读:探索技术细节与误区,"['C语言', '编译原理', '程序设计', '编程规范', '技术解析']
摘要由CSDN通过智能技术生成

首先声明,由于我太菜了,本文很多式子可能并不会有详细的证明。若要了解莫比乌斯反演最基本的证明,可以去这里,本文主要讲解一些套路。

莫比乌斯函数

我们定义莫比乌斯函数如下:
设 n = ∏ i = 1 m p i a i , k = ∏ i = 1 m a i μ ( n ) = { 1 ( n = 1 ) ( − 1 ) m ( k = 1 ) 0 ( k > 1 ) 设n=\prod_{i=1}^{m} p_i^{a_i},k=\prod_{i=1}^{m} a_i \\ \mu(n)= \begin{cases} 1 & (n=1) \\ (-1)^{m} & (k=1) \\ 0 & (k>1) \end{cases} n=i=1mpiai,k=i=1maiμ(n)=1(1)m0(n=1)(k=1)(k>1)
然后我们会发现它是一个积性函数,可以用线性筛 O ( n ) ​ O(n)​ O(n)求出 1 − n ​ 1-n​ 1n的莫比乌斯函数。代码如下:

mu[1] = 1;
for(int i = 2; i <= n; i++){
   
    if(!mark[i]){
   
        p[++cnt] = i;
        mu[i] = -1;		//质数显然k=1
    }
    for(int j = 1; j <= cnt && p[j]*i <= n; j++){
   
        mark[p[j]*i] = 1;
        if(i%p[j] == 0) break;
        mu[i*p[j]] = -mu[i];	//由于欧拉筛中,每个数只会被最小的质因子筛到一次,相当于这个数多了一个因子p[j],就相当于-mu[i](可以通过分类讨论理解)。
    }
}

同时,莫比乌斯函数还满足:
∑ i = 1 n μ ( i ) = [ n = 1 ] \sum_{i=1}^{n}\mu(i)=[n=1] i=1nμ(i)=[n=1]
这也是一个美妙的性质(可惜我不会证)。


莫比乌斯反演

依然直接扔公式(是的,我也不会证):

若函数 f ( n ) f(n) f(n) g ( n ) g(n) g(n)是数论函数,且满足:
g ( n ) = ∑ d ∣ n f ( d ) g(n)=\sum_{d|n}f(d) g(n)=dnf(d)
那么有如下结论:
f ( n ) = ∑ d ∣ n g ( d ) × μ ( n d ) f(n)=\sum_{d|n}g(d)\times \mu(\frac{n}{d}) f(n)=dng(d)×μ(dn)
实际上,在做题过程中也会遇到上述式子中的 d ∣ n d|n dn变为 n ∣ d n|d nd,式子依然成立,但此时 d d d往往有明确的上限。


经典套路

以下默认 n ≤ m n\leq m nm

1.求(i,j)=x的个数

这是莫比乌斯反演最经典的应用。

给定 n , m n,m n,m,求 f ( x ) = ∑ i = 1 n ∑ j = 1 m [ ( i , j ) = x ] ​ f(x)=\sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m}[(i,j)=x]​ f(x)=i=1nj=1m[(i,j)=x]

我们设 g ( x ) = ∑ i = 1 n ∑ j = 1 m [ x ∣ ( i , j ) ] g(x)=\sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m}[x|(i,j)] g(x)=i=1nj=1m[x(i,j)]。那么我们发现显然 g ( x ) = ∑ x ∣ d f ( d ) g(x)=\sum\limits_{x|d}f(d) g(x)=xdf(d)。此处 d d d的上限为 n n n

于是我们套公式,直接反演一波:
f ( x ) = ∑ x ∣ d g ( d ) × μ ( d x ) 。 f(x) = \sum_{x|d}g(d)\times \mu(\frac{d}{x})。 f(x)=xdg(d)×μ(xd)
我们为啥这么麻烦的反演呢?当然是因为 g ( x ) ​ g(x)​ g(x)比较好求。我们观察 x ∣ ( i , j ) ​ x|(i,j)​ x(i,j)这个条件,发现 i , j ​ i,j​ i,j均可以表示成 x × k ​ x\times k​ x×k,于是在 n ​ n​ n

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值