Loading

莫比乌斯反演总结

懵逼乌斯反演总结

前置知识

1.1 线性筛 (欧拉筛)

int prime[N] , tot ;
bool is[N] ;
void get_prime( int n )
{
	is[0] = is[1] = 1 ;
	for(int i = 2 ; i <= n ; i ++ ) {
		if( !is[i] ) {
			prime[++tot] = i ;
		}
		for(int j = 1 ; j <= tot && i*prime[j] <= n ; j ++ ) {
			is[i*prime[j]] = 1 ;
			if( i%prime[j] == 0 ) {
				break ;
			}
		}
	}
}

需要注意的是,线性筛有着非常优秀的性质

对于每个数,一定是被其 最小质因子 标记的

换句话说,对于一个数 \(n=p_1^{a_1}p_2^{a_2}...p_k^{a_k}\),它被标记的过程一定是 \(1\) 开始,每次加入当前最大的因子,即 \(p_k\),然后 \(p_{k-1}\),直到把 \(p_1\) 加完,就标记到了

线性筛可以高效的计算某些数论函数的值,但对于不同的函数可能有不同的处理方式

1.2 整除分块 (数论分块)

考虑计算:$$\sum_{i=1}^n \left \lfloor \frac{n}{i} \right \rfloor $$

其中 \(n\leq10^{12}\)

研究 \(\left \lfloor \frac{n}{i} \right \rfloor\) 这个函数,首先它随 \(i\) 增大单调不升;其次,会有很多数值相等的段

在这里插入图片描述

这启发我们:将相同的一段打包计算!

引理 1

\[\forall a,b,c\in\mathbb{Z} , \left \lfloor \frac{a}{bc} \right \rfloor=\left \lfloor \frac{\left\lfloor \frac{a}{b}\right\rfloor}{c} \right \rfloor \]

在这里插入图片描述
摘自 oi.wiki

引理 2

  \(\large\left \lfloor \frac{n}{i} \right \rfloor\) 的取值种类不会超过 \(\left\lfloor 2\sqrt n \right\rfloor\)

在这里插入图片描述

这个引理也告诉我们:段数 \(\sqrt n\) 的结论是 均摊 的结果!

引理 3

对于常数 \(n\),使得式子 $$\left\lfloor\frac{n}{i}\right\rfloor=\left\lfloor\frac{n}{j}\right\rfloor$$ 成立且满足 \(i\leq j\leq n\) 的最大的 \(j\)\(\large\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloor\)

这个式子告诉我们如何寻找左端点为 \(l\) 的段的右端点

实现

数论分块可以在 \(O(\sqrt n)\) 的复杂度内解决形如

\[\sum_{i=1}^n\left\lfloor\frac{n}{i}\right\rfloor f(i)$$ 的求和式 需要能够快速得到 $f$ 在某一段区间的 $sum$ 要么是预处理前缀和,要么可以借助数学知识直接得到式子 基本模板: ```cpp int l = 1 , r ; while( l <= n ) { r = n/(n/l) ;// 找到右端点 // 对 i:[l,r], 这个取整式是一个定值 ans -= 1LL*(K/l)*calc(l,r) ; l = r+1 ; } ``` ### 例 1 求:$$\sum_{i=1}^k\left\lfloor\frac{n}{i}\right\rfloor\left\lfloor\frac{m}{i}\right\rfloor\]

二维数论分块,为了保证同一段内取值的一定性,\(r\) 应该取较小的那个转折点

	k = min(n,m) ;
	int l = 1 , r ;
	while( l <= k ) {
		r = min( n/(n/l) , m/(m/l) ) ;
		ans += 1LL*(n/l)*(m/l)*calc(l,r) ;
		l = r+1 ; 
	}

在这里插入图片描述

\(d\) 维数论分块的复杂度为 \(O(d\sqrt n)\)

例 2

上取整数论分块

注意到 \(\left \lceil \frac{n}{i} \right \rceil=\left\lfloor\frac{n-1}{i}\right\rfloor+1\)

所以 \(n\) 的上取整分块等价于 \(n-1\) 的下取整分块

需要注意分母不为 \(0\)

例 3

CF1780E

好难的题

一句话题意:对于 \(x,y\in[l,r]\),求 \(gcd(x,y)\) 的种类数

\(l\leq 10^9,r\leq10^{18}\)

考虑每个 \(gcd\) 能否出现

能想到的是对于 每个 \(d\) 可以找到区间 \([l,r]\) 中所有它的倍数,然后没法了,不知道怎么恰好取到 \(d\)

但我们会发现 :\(gcd(kd,(k+1)d)=d\) ,也就是说 \([l,r]\)只要有两个及以上 \(d\) 的倍数,那么任取相邻的两个就行

分析一下,当 \(l\leq d\leq r\) 时,\(d\) 本身就在区间中出现一次了,那么只需 \(2\times d\leq r\) 即可,这部分可以 \(O(1)\)

接下来,就是要求 $$\sum_{d=1}^l[\left \lceil \frac{l}{d} \right \rceil < \left\lfloor \frac{r}{d}\right\rfloor]$$

枚举 \(d\) 复杂度还是不行,我们数论分块

一个朴素想法是同时对 \(l,r\) 分块,但对 \(r\) 分块的复杂度是 \(O(\sqrt {10^{18}})\),寄

那么只能对 \(l\) 分块了,确定了 \(\large\left \lceil \frac{l}{d} \right \rceil\) 的值后,合法的 \(r\) 就成了一段区间,可以 \(O(1)\) 算范围

复杂度 \(O(\sqrt l)\)

int T ;
LL l , r , ans ;
void solve()
{
	// d>=l
	ans = max((r/2)-l+1,0LL) ;
	// d < l
	if( l > 1 ) { // 不能让分母为 0
		LL L = 1 , R = 0 ;
		while( L < l ) {
			R = (l-1)/((l-1)/L) ;
			LL x = (l-1)/L+1+1 , rr = r/x ;
			
			rr = max(0LL,rr-2) ;
			while( x<=r/(rr+1) ) rr++ ;//这两行是抹平微小的误差
			
			rr = min(rr,R) ;
			ans += max(0LL,rr-L+1) ;
			L = R+1 ;
		}
	}
	printf("%lld\n" , ans ) ;
}

例 4

[清华集训2012] 模积和

一个小学生都知道的结论:\(n\mod i=n-\left\lfloor\frac{n}{i}\right\rfloor i\)

然后就是化化式子


1.3 数学知识

积性函数

定义:若 \(\forall x,y\) 满足 \(gcd(x,y)=1\),都有 \(f(xy)=f(x)\times f(y)\),则 \(f\) 为积性函数

特别的,若不需要 \(x,y\) 互质的条件,\(\forall x,y\) 都有 \(f(xy)=f(x)f(y)\),称 \(f\) 为完全积性函数

常见的积性函数:

  • 单位函数 \(e(n)=[n=1]\) ,完全积性
  • 幂函数 \(\mathrm{Id}_k(n)=n^k\)\(\mathrm{Id}_1\) 通常简记为 \(id\),完全积性
  • 常数函数 \(1(n)=1\),完全积性
  • 约数函数 \(\sigma_k(n)=\sum_{d|n}d^k\) ,积性
    特别的,\(k=0\) 时为约数个数函数,可记为 \(d(n)\)\(k=1\) 时为约数和函数,记为 \(\sigma(n)\)
  • 欧拉函数 \(\varphi(n)=\sum_{i=1}^n[gcd(n,i)=1]\),积性
  • 莫比乌斯函数 \(\mu(n)=\begin{Bmatrix} 1& n=1 \\ 0& n含有平方因子\\ (-1)^k& k为n的不同质因子个数 \end{Bmatrix}\),积性

莫比乌斯函数

\(\mu(n)=\begin{Bmatrix} 1& n=1 \\ 0& n含有平方因子\\ (-1)^k& k为n的不同质因子个数 \end{Bmatrix}\)

形式很奇怪,但实际上它反映了一种 对每个约数考虑的容斥系数

第二条说人话就是:若存在某个质数 \(p\)\(n\) 的质因子分解中 \(p\) 的指数 \(\geq 2\),则 \(\mu(n)=0\)

性质

\[\sum_{d|n}\mu(d)=[n=1] \]

证明:

\(n=p_1^{a_1}...\ p_k^{a_k}\)

显然当 \(d\) 取到的某个质因子指数 \(\geq 2\) 是没有贡献的,只需考虑 \(0,1\) 的情况

\(k\) 个质因子中取 \(i\) 个指数为 \(1\),那么原和式即为:$$\sum_{i=0}kC_ki(-1)i=(1-1)k=[k=0]$$

( 最后一步相信你是理解的

\([n=1]\),证毕

求法

积性函数,直接线性筛,好写

int mu[N] , prime[N] , tot ;
bool is[N] ;
void get_Mu( int n )
{
	is[0] = is[1] = 1 ; mu[1] = 1 ;
	for(int i = 2 ; i <= n ; i ++ ) {
		if( !is[i] ) {
			prime[++tot] = i ;
			mu[i] = -1 ;
		}
		for(int j = 1 ; j <= tot && prime[j]*i <= n ; j ++ ) {
			is[i*prime[j]] = 1 ;
			if( i%prime[j] == 0 ) {
				mu[i*prime[j]] = 0 ;//已经加过这个因子了
				break ;
			}
			else mu[i*prime[j]] = -mu[i] ;//换了一种因子加
		}
	}
}

狄利克雷(Dirichlet)卷积

定义两个数论函数 \(f,g\) 的狄利克雷卷积为 $$(f*g)(n)=\sum_{d|n}f(d)g(\frac{n}{d})$$ 简单点说就是你一半,我一半,再求和

性质

  1. 满足交换律、结合律、分配律

  2. \(f,g\) 为积性函数,\(f*g\) 也为积性函数 (快速判断一个函数好不好筛)

  3. \(e\) 为狄利克雷卷积的单位元,即 \((f*e)(n)=f(n)\)

    \(e=\mu*1=\sum_{d|n}\mu(d)\)

    证明:$$(f*e)(n)=\sum_{d|n}f(d)e(\frac{n}{d})=\sum_{d|n}f(d)\sum_{k|\frac{n}{d}}\mu(k)=\sum_{d|n}f(d)[\frac{n}{d}=1]$$

    最后一步用了 \(\mu\) 函数的性质

    显然只有当 \(n=d\) 时才有贡献,贡献为 \(f(n)\)

    所以 \(e=\mu *1\) 满足单位元的性质

一些神奇的结论

  • \(\mathrm{Id_k}*1=\sigma_k\)

  • \(\varphi*1=id\)
    更常见的形式是 $$n=\sum_{d|n}\varphi(d)$$

    相信聪明的你一定会证明的 (利用积性函数的性质)

  • \(\varphi=\mathrm{Id}*\mu\) ,学过的两个函数就神奇地建立了联系!

计算

\[(f*g)(n)=\sum_{d|n}f(d)g(\frac{n}{d}) \]

  • 求单个函数值:\(O(\sqrt n)\) 暴力枚举因子
  • \([1\sim n]\) 所有函数值:
    1. 暴力卷积,枚举 \(d\),枚举倍数,复杂度 \(O(n\mathrm{log\ n})\) ,忽略了计算 \(f,g\) 的复杂度
    2. 有些时候的 “卷积” 是只和质因子有关的,Dirichlet 前缀和可以做到 \(O(n\mathrm{log logn)}\)
    3. 更常见的,发现这个函数的某些性质,用线性筛筛出所有函数值,复杂度 \(O(n)\)


莫比乌斯反演

2.1 公式

\(f,g\) 为两个数论函数

如果有 $$f(n)=\sum_{d|n}g(d)$$ 那么 $$g(n)=\sum_{d|n}f(d)\mu(\frac{n}{d})$$

学会了狄利克雷卷积后,证明就变得十分简单

\(1\) 式等价于:\(f=g*1\)

\(2\) 式等价于:\(g=f*\mu\)

只需要 \(2\) 式两边同时卷上一个 \(1\) 即证

2.2 常用唯一结论

\[[gcd(i,j)=1]=\sum_{k|i,k|j}\mu(k) \]

拆开即可

2.3 例题

例 1

求全由小写字母组成、长度为 \(n\) 的周期性字符串的个数

周期性字符串的定义是 可以由至少一个子串重复大于等于两次得到的字符串

\(n\leq10^6\)

\(f(n)\) 表示长度为 \(n\) 的所有串,\(g(n)\) 表示长度为 \(n\),不具有周期的串

\(f(n)=\sum_{d|n}g(d)\) ,反演得 \(g(n)=\sum_{d|n}f(d)\mu(\frac{n}{d})\)

\(f\) 的求法是显然的,那么最终答案 \(f(n)-g(n)\)

感觉是不太符合直觉,但很优秀的做法

例 2

求:\(\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=1]\) ,互质数对的个数

\(n,m\leq10^{12}\)

直接套用结论

\(=\sum_{i=1}^n \sum_{j=1}^m \sum_{k|i,k|j}\mu(k)\)

考虑每个 \(\mu(k)\) 会贡献几次

\(=\sum_{k=1}^m\mu(k)\sum_{i=1}^{[n/k]}\sum_{j=1}^{[m/k]}1\)

\(=\sum_{k=1}^m\mu(k) \left\lfloor\frac{n}{k}\right\rfloor \left\lfloor\frac{m}{k}\right\rfloor\)

直接数论分块

例 3

求 $$\sum_{i=1}^n \sum_{j=1}^m ij[gcd(i,j)=k]$$

\(n,m,k\leq 10^{12}\) ,对质数取模

与上一题有两点不同:带系数、不是互质;这么做:

$\sum $

posted @ 2024-09-01 15:07  forgive_void  阅读(57)  评论(0)    收藏  举报