关于反演和积性函数

先开个天坑,慢慢补(

Legitimity 的数学一直是拖后腿的一项,学的时候很云里雾里,但又必须要补,像数论这一块也学了就忘,忘了再学,现在开始整理整理,也供后人参考和批评。

本文旨在感性理解关于反演(包括但不限于莫比乌斯反演),适于 NOIP 前恶补这方面知识的选手,不保证每处证明都严谨。

不保证文中每一份代码都编译过。

若无特殊说明,本文 \(\ast\) 符号特指狄利克雷卷积运算。

(马上要期末考试了,可能会有点咕)

前置知识:

1.数论分块

假如要求这样一个东西:

\[\sum_{i=1}^{n}f_i\lfloor\dfrac{n}{i}\rfloor \]

其中 \(f\) 是一个已知的函数。

我会 \(O(n)\) 暴力!

观察 \(\lfloor\dfrac{n}{i}\rfloor\) 的取值变化,发现其中有一些值是相同的,并且这些相同的值都处于连续的一段。(废话)

预处理 \(f\) 的前缀和 \(S\) 之后,对于值相同的一段,我们可以一起处理,具体而言:

\[ans=\sum_{i=1}^{k}value_i\times(S_{r_i}-S_{l_i-1}) \]

复杂度为 \(O(k)\)\(k\) 为取值的个数)。

那么不同的值最多有多少个?

答案是 \(2\sqrt n\) 个。

怎么证?

对于 \(i\leq \sqrt n\)\(i\) 的最大值为 \(\sqrt n\),所以 \(i\) 的取值只有 \(\sqrt n\) 个,所以 \(\lfloor\dfrac{n}{i}\rfloor\) 的取值最多也只有 \(\sqrt n\) 个。

对于 \(i\geq\sqrt n\)\(i\) 的最小值为 \(\sqrt n\)\(\lfloor\dfrac{n}{i}\rfloor\) 的最大值为\(\sqrt n\),所以 \(\lfloor\dfrac{n}{i}\rfloor\) 的取值最多也只有 \(\sqrt n\) 个。

总共最多 \(2\sqrt n\) 个。


如何实现?

\(\lfloor\dfrac{n}{i}\rfloor\) 最左端出现在哪?显然是上一块(上一个取值)的最右端 \(+1\)

\(\lfloor\dfrac{n}{i}\rfloor\) 最右端出现在哪?这时需要 \(i\) 最大,计最大值为 \(j\),感性理解一下,\(j\) 显然是 \(\lfloor\dfrac{n}{\frac{n}{i}}\rfloor\),严谨证明请去 oiwiki。

那么代码也就简单了,这里以求 \(\sum_{i=1}^{n}i\lfloor\dfrac{n}{i}\rfloor\) 为例:

inline int work(int n){
	int ret=0;
	for(rg int l=1,r=0;l<=n;l=r+1){
		r=n/(n/l);
		ret+=(l+r)*(r-l+1)/2*(n/l);
	}
	return ret;
}

拓展:

其实对于

\[\sum_{i=1}^{\min(n,m)}f_i\lfloor\dfrac{n}{i}\rfloor\lfloor\dfrac{m}{i}\rfloor \]

这样的柿子,也是可以数论分块的,只是块的个数增加到了 \(2\sqrt n+2\sqrt m\) 个。以此类推,更多个套在一起都能数论分块。

放个代码(以 \(\sum_{i=1}^{\min(n,m)}i\lfloor\dfrac{n}{i}\rfloor\lfloor\dfrac{m}{i}\rfloor\) 为例):

inline int work(int n,int m){
	int ret=0;
	if(n<m) swap(n,m);
	for(rg int l=1,r=0;l<=n;l=r+1){
		r=min(n/(n/l),m/(m/l));
		ret+=(l+r)*(r-l+1)/2*(m/l)*(n/l);
	}
	return ret;
}

练手题:

P2261[CQOI2007]余数求和

P2260 [清华集训2012]模积和

P6788「EZEC-3」四月樱花


2.积性函数求和(线性筛、埃氏筛)

上面的数论分块的前提是得到了 \(f\) 的前缀和 \(S\) ,现在要考虑如何快速求出这个 \(S\)

之前的柿子是太水了,\(O(1)\) 能直接搞出前缀和,那么换个柿子:

\[\sum_{i=1}^{n}\varphi(i)\lfloor\dfrac{n}{i}\rfloor \]

( \(\varphi\) 显然是个积性函数)。


大家应该都知道如何用埃氏筛或线性筛去筛质数吧?

以线性筛为例,考虑一下筛的过程:

int pr[500005],cnt;
bool vis[5000005];
void work1(int n){
	vis[1]=1;
	for(rg int i=2;i<=n;++i){
		if(!vis[i]){
			pr[++cnt]=i;
		}
		for(rg int j=1;j<=cnt&&i*pr[j]<=n;++j){
			vis[i*pr[j]]=1;
			if(i%pr[j]==0)
				break;
		}
	}
}

我们发现,当 \(i\) 被筛的时候,无非有三种情况:

  1. \(i\) 是质数,自己筛自己。
  2. \(i\) 被自己最小的质因子筛,最小的质因子只出现一次(即 \(p_{min}\mid i\)\(p_{min}^2\nmid i\))
  3. \(i\) 被自己最小的质因子筛,最小的质因子超过一次(即\(p_{min}^2\mid i\) )

回顾积性函数的定义

\[f(ab)=f(a)\times f(b)(\gcd(a,b)=1) \]

分别对应上面的三种情况:

  1. \(i\) 是质数,有特殊性质,自立根生(\(\varphi(i)=i-1\))。
  2. \(i\) 被自己最小的质因子筛,最小的质因子只出现一次(即 \(p_{min}\mid i\)\(p_{min}^2\nmid i\)),此时 \(\gcd(p_{min},\dfrac{i}{p_{min}})=1\),那么直接 \(f(i)=f(p_{min})\times f(\dfrac{i}{p_{min}})\)
  3. \(i\) 被自己最小的质因子筛,最小的质因子超过一次(即\(p_{min}^2\mid i\) )此时情况就比较复杂,要针对不同的积性函数做不同的分类讨论。(对于一些常见的函数,这个讨论都比较简单)

对于 \(\varphi\),第三类情况怎么做?

考虑 \(\varphi\) 的一条性质:
\(p^2\mid n\),则 \(\varphi(n)=\varphi(\dfrac{n}{p})\times p\)

那么就直接套:

ll phi[5000005];
int pr[500005],cnt;
bool vis[5000005];
void work(int n){
	phi[1]=1; vis[1]=1;
	for(rg int i=2;i<=n;++i){
		if(!vis[i]){
			pr[++cnt]=i;
			phi[i]=i-1;
		}
		for(rg int j=1;j<=cnt&&i*pr[j]<=n;++j){
			vis[i*pr[j]]=1;
			phi[i*pr[j]]=phi[i]*phi[pr[j]];
			if(i%pr[j]==0){
				phi[i*pr[j]]=phi[i]*pr[j];
				break;
			}
		}
	}
	for(rg int i=1;i<=n;++i)
		phi[i]+=phi[i-1];
}

题外话:对于一般的积性函数的前缀和,做法是先求出两个函数 \(T(p,c)\)\(G(p)\),其中 \(T\) 是关于 \(p,c\) 的多项式函数。\(n\) 为质数时,\(f(n)=G(n)\)\(n=p^c\)\(p\) 为质数)时,\(f(n)=T(p,c)\)。这样就解决了第一、第三类的转移,所以就可以由这两个函数在递推中求出目标积性函数(具体的在任之洲的论文有讲,不过其实这样的做法一般用于洲阁筛和 Min_25 筛,因为复杂度可以低于线性,用于线性筛就大材小用了。线性筛一般求 \(\mu\)\(\varphi\)\(\sigma\) 就够了 )


3.狄利克雷卷积(Dirichlet 卷积)

定义一种对于两个函数的运算 \(\ast\)

\[f\ast g (n)=\sum_{d|n}f(d)\times g(\dfrac{n}{d}) \]

其中 \(f\ast g\) 称之为 \(f\)\(g\) 的狄利克雷卷积。

上式也可以写成:

\[f\ast g (n)=\sum_{d|n}f(\dfrac{n}{d})\times g(d) \]

两者本质上是一样的。

关于狄利克雷卷积,有一些有意思的性质:

  1. 如果函数 \(f\)\(g\) 为积性函数,那么 \(f\ast g\) 也是积性函数。
  2. 定义单位元函数 \(\epsilon(n)=[n=1]\),如果函数 \(f\) 为积性函数,那么有 \(f=f\ast \epsilon\)
  3. 如果函数 \(f\) 为积性函数,找到一个函数使得 \(f\ast g=\epsilon\),那么称 \(g\)\(f\) 的逆元(狄利克雷卷积意义下),且 \(g\) 也是积性函数。
  4. 交换律:\(f\ast g=g\ast f\)
  5. 结合律:\(f\ast g \ast p=f\ast (g\ast p)\)
  6. 分配律:\(f\ast(g+p)=f\ast g+f\ast p\)
  7. \(f=g\),则 \(f\ast p=g \ast p\)

接下来反演的众多变换都是基于狄利克雷卷积的这几个性质。


正文:

what is 反演

假设我们要求一个奇怪和式(主要是和式)套一个奇怪的函数,设这个奇怪的函数为 \(f\)

但是我们发现暴力计算复杂度过高,那么我们就考虑不直接计算 \(f\),而是将 \(f\) 写成两个函数卷积(各种各样的卷积)的形式,通过计算贡献的方式来求出这个柿子。

形式化的将,就是:

\[f(n)=\sum_{k}h(n,k)\times g(k) \]

也就是(\(\ast\) 为一种奇怪的卷积运算。):

\[f=h\ast g \]

(其实这里不严谨,严格意义上来说 \(h\) 并不是一个函数)

通过计算不同 \(g\) 的贡献来达到求 \(f\) 的效果。

而已知函数 \(f\)\(g\) 的、利用 \(g\)\(f\) 的过程我们就称之为反演


莫比乌斯反演

莫比乌斯函数 \(\mu\) 应该都知道吧?

都假装不知道来让我讲一下。

根据算术基本定理,\(n=\prod_{i=1}^{k}p_i^{c_i}\)\(p\) 为质数)

那么:

\[\mu(n)= \begin{cases} 0& {\exists i \in [1,k],c_i>1}\\ 1&{k\equiv 1(\bmod 2),\forall i \in[1,k],c_i=1}\\ -1&{{k\equiv 0(\bmod 2),\forall i \in[1,k],c_i=1}} \end{cases} \]

还有另外一种形式:

\[\mu(n)= \begin{cases} 0& {\exists i \in [1,k],c_i>1}\\ (-1)^k& \text{otherwise} \end{cases} \]

特别的,\(\mu(1)=1\)


说人话?

\(n\) 有幂次大于 \(1\) 的质因子时,\(\mu(n)=0\);否则,若 \(n\) 有偶数个质因子时,\(\mu(n)=1\),若 \(n\) 有奇数个质因子时,\(\mu(n)=-1\)


\(\mu\) 有什么特殊的性质吗?乍一看这个鬼畜的定义看不出它有什么直观的描述方法,若硬要给它一个形象的定义,\(\mu\) 其实可以看成是数论意义上的容斥系数。

还是不够特殊?那么先给出一个结论(这一条是莫比乌斯反演中最常用的,个人感觉比莫比乌斯反演定理更常用):

\[\mu\ast\operatorname{1}=\epsilon \]

也就是:

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

why?

根据算术基本定理,令 \(n=\prod_{i=1}^{k}p_i^{c_i}\)\(n'=\prod_{i=1}^{k}p_i\)

则: \(\sum_{d|n}\mu(d)=\sum_{d|n'}\mu(d)\)

因为当幂次大于一时,\(\mu\) 的值为 \(0\),可以直接忽略。

且:\(\sum_{d|n'}\mu(d)=\sum_{i=0}^k\binom i k \times(-1)^i\) (废话)

所以 \(\sum_{d|n}\mu(d)=\sum_{i=0}^k\binom i k \times(-1)^i\)

我们发现后边这一坨就是 \(\sum_{i=0}^k\binom i k \times1^{k-i}\times(-1)^i\),根据二项式定理可得:

\(\sum_{d|n}\mu(d)=\sum_{i=0}^k\binom i k \times1^{k-i}\times(-1)^i=(1+(-1))^k=0^k\)

且当 \(k=0\)\(n=1\) 时,\(0^k=1\)

所以 \(n=1\) 时,\(\sum_{d|n}\mu(d)=1\),否则,\(\sum_{d|n}\mu(d)=0\)

\(\mu\ast\operatorname{1}=\epsilon\)


好了,有了这个结论,我们就可以做题了。

problem:

给定 \(n,m\),求 \(1\leq a\leq n\)\(1\leq b\leq m\)\(a,b\) 互质的有序对数。

solution:

不难发现,答案即为:

\[\sum^n_{i=1}\sum^m_{j=1}[\gcd(i,j)=1] \]

推!

\[ans=\sum^n_{i=1}\sum^m_{j=1}\epsilon(\gcd(i,j)=1) \]

\[ans=\sum^n_{i=1}\sum^m_{j=1}\sum_{d|i,d|j}\mu(d) \]

改变求和顺序:

\[ans=\sum_{d=1}^{\min(n,m)}\mu(d)\sum^n_{i=1}\sum^m_{j=1}[d|i,d|j] \]

\[ans=\sum_{d=1}^{\min(n,m)}\mu(d)\lfloor\dfrac{n}{d}\rfloor\lfloor\dfrac{m}{d}\rfloor \]

此时就可以 \(O(n)\) 求解。如果多组询问,那么先线性筛出 \(\mu\) 的前缀和,每次再数论分块求解,复杂度为 \(O(n+q\sqrt n)\)

problem:

给定 \(n,m\),求 \(1\leq a\leq n\)\(1\leq b\leq m\) 中满足 \(\gcd(a,b)\) 是质数的有序对数。

solution:

不难发现,答案即为:

\[\sum^n_{i=1}\sum^m_{j=1}[\gcd(i,j)\text{is a prime}] \]

枚举 \(\gcd(i,j)\)

\[ans=\sum_{p\text{is a prime}}\sum^n_{i=1}\sum^m_{j=1}[\gcd(i,j)=p] \]

\[ans=\sum_{p\text{is a prime}}\sum^{\lfloor\frac{n}{p}\rfloor}_{i=1}\sum^{\lfloor\frac{m}{p}\rfloor}_{j=1}[\gcd(i,j)=1] \]

哇!和上面一样:

\[ans=\sum_{p\text{is a prime}}\sum_{d=1}^{\min(\lfloor\frac{n}{p}\rfloor,\lfloor\frac{m}{p}\rfloor)}\mu(d)\lfloor\dfrac{n}{pd}\rfloor\lfloor\dfrac{m}{pd}\rfloor \]

此时已经比较优了,直接计算复杂度为:\(O(\dfrac{n^2}{\ln n})\),多组询问可以做到 \(O(n+q\dfrac{n\sqrt n}{\ln n})\),但是还不够,我们可以继续优化。

\(pd\) 太丑了,换元:

\[ans=\sum_{p\text{is a prime}}\sum_{p|T}^{\min(n,m)}\mu(\dfrac{T}{p})\lfloor\dfrac{n}{T}\rfloor\lfloor\dfrac{m}{T}\rfloor \]

把枚举质数扔到后面:

\[ans=\sum_{T=1}^{\min(n,m)}\lfloor\dfrac{n}{T}\rfloor\lfloor\dfrac{m}{T}\rfloor\sum_{p\text{is a prime},p|T}\mu(\dfrac{T}{p}) \]

然后我们发现:前面的,可以数论分块 \(O(\sqrt n)\) 解决,后面的在线性筛(也可以埃氏筛,因为瓶颈不在筛 \(\mu\))筛出 \(\mu\) 之后,可以用埃氏筛 \(O(n\ln n)\approx O(n\log n)\) 提前预处理。

然后就做完了:

int t,n,m;
ll ans,g[10000005];
int mu[10000005],pr[1000005],cnt;
bool vis[10000005];
void work(int n){
	mu[1]=1;
	for(rg int i=2;i<=n;++i){
		if(!vis[i]){
			pr[++cnt]=i;
			mu[i]=-1;
		}
		for(rg int j=1;j<=cnt&&i*pr[j]<=n;++j){
			vis[i*pr[j]]=1;
			mu[i*pr[j]]=-mu[i];
			if(i%pr[j]==0){
				mu[i*pr[j]]=0;
				break;
			}
		}
	}
	for(rg int j=1;j<=cnt;++j){
		for(rg int i=1;i*pr[j]<=n;++i){
			g[i*pr[j]]+=mu[i];
		}
	}
	for(rg int i=1;i<=n;++i)
		g[i]+=g[i-1];
}
int main(){
	t=read();
	work(10000005);
	while(t--){
		n=read(); m=read(); ans=0;
		if(n>m) swap(n,m);
		for(rg int l=1,r;l<=n;l=r+1){
			r=min(n/(n/l),m/(m/l));
			ans+=1ll*(n/l)*(m/l)*(g[r]-g[l-1]);
		}
		printf("%lld\n",ans);
	}
	return 0;
} 

诶,不对啊,到目前为止,我们做的题目虽然和莫比乌斯有关系,但好像和我们之前对于反演的定义没啥关系诶。

确实没有关系。

大部分情况下 \(\mu * 1=\epsilon\) 就够了。

但是,我们还是要正确的去认识一下莫比乌斯反演定理。

莫比乌斯反演定理:

\(f\)\(g\) 是两个积性函数,

  1. 如果有 \(f(n)=\sum_{d|n}g(d)\),那么有 \(g(n)=\sum_{d|n}\mu(\dfrac{n}{d})\times f(d)\)
  2. 如果有 \(f(n)=\sum_{n|d}g(d)\),那么有 \(g(n)=\sum_{n|d}\mu(\dfrac{d}{n})\times f(d)\)(这个不怎么常用,其实也就是第一个的逆推)。

why?

考虑证明第一个,第二个逆推第一个的过程就行了。

第一个柿子本质上就是:

\[f=g\ast 1\implies g=\mu \ast f \]

对于原式,两侧同时卷上 \(\mu\)

\[f\ast \mu=g\ast 1\ast \mu \]

结合律:

\[f\ast \mu=g\ast(1\ast \mu) \]

哇!\(1\ast \mu\) 是什么?

\[f\ast \mu=g\ast\epsilon=g \]

那么这有什么用?

来看一道题:

problem:

多组询问,每组询问给定 \(n,m,a\),求:

\[\sum_{i=1}^n\sum_{j=1}^m\sigma_1(\gcd(i,j))[\sigma_1(\gcd(i,j))\leq a]\pmod {2^{31}} \]

solution:

首先考虑没有 \(a\) 的限制怎么做。

先扔个结论:

\[\sigma_1=1\ast \operatorname{id} \]

why?

这个证明很简单,考虑 \(\sigma_1\) 的定义:约数和,即 \(\sigma_1(n)=\sum_{d|n}d\),仔细看看就能发现这就是 \(\sigma_1=1\ast \operatorname{id}\)

然后就可以和例题 1 一样快快乐乐的推柿子了:

\[ans=\sum_{i=1}^n\sum_{j=1}^m\sigma_1(\gcd(i,j)) \]

\[ans=\sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j}d \]

\[ans=\sum_{d=1}^{\min(n,m)}d\sum_{i=1}^n\sum_{j=1}^m[d|i,d|j] \]

\[ans=\sum_{d=1}^{\min(n,m)}d\lfloor\dfrac{n}{d}\rfloor\lfloor\dfrac{m}{d}\rfloor \]

又是一个典型的数论分块,连预处理前缀和都不用,\(O(q\sqrt n)\) 秒了它。

等等,原题是有小于 \(a\) 的限制的。

但是盯着我们推完的柿子,发现很难把 \(\sigma_1\leq a\) 的限制嵌进去。因为在把 \(\sigma_1\) 反演成 \(\operatorname{id}\) 过程中,我们好像丢失 \(\sigma_1\) 的信息,仅仅有“已知 \(g\)\(f\) ”的过程,也就是我们这里是“单向反演”,并不符合我们上面反演的定义。

但是,我们现在有莫比乌斯反演定理!

\[\sigma_1=1\ast \operatorname{id}\implies \operatorname{id}=\mu \ast \sigma_1 \]

我们在 \(\sigma_1\)\(\operatorname{id}\) 之间找到了相互转换的关系,可以通过限制 \(\sigma_1\) 来限制 \(\operatorname{id}\)

那么就有一个显然的做法了:将询问离线下来按 \(a_i\) 升序排序,\(a_i\) 是递增的,那么每次就可以将满足条件的 \(\sigma_1(j)\)\(\operatorname{id}(k)\) 的贡献加进去,数论分块到 \(l,r\) 时,查询满足 \(1\leq k\leq r\)\(\operatorname{id}(k)\) 已被 \(\sigma_1\) 贡献过的值

梳理一下,这题需要我们干什么?

快速询问:

\[\sum_{\sigma(i)\leq a,j\leq x,i|j}\operatorname{id}(j) \]

就是一个显然的带一个整除限制的二维偏序,本题的 \(n\) 比较小,可以直接双指针+树状数组,如果 \(n,m\) 的值比较大,且这题貌似也不好离散化(如果会处理的神仙可以教我一下吗?),就可以 cdq 分治来维护,两者的代码都很好写。

另外要注意一个地方,在双指针+树状数组的外层双指针算贡献(或 cdq 分治中的归并排序打标记贡献)中,\(\sigma_1(i)\)\(\operatorname{id}(j)\) 的贡献是 \(\mu(\dfrac{j}{i})\times \sigma_1(i)\)

这题还有一个卡常小技巧,因为模数是 \(2\) 的整数次幂(\(2^{31}\)),可以在运算过程中用 unsigned int (32 位无符号整型)保存自然溢出,最终取后 \(31\) 位(即 ans&((1ll<<31)-1)输出。

时间复杂度:双指针+树状数组维护二维偏序本身是 \(O(n\log V)\) 的,但是为了维护整除限制,双指针内还套了一层埃氏筛,所以复杂度是 \(O(n \ln n\log n)\approx O(n \log^2 n)\),而数论分块部分的复杂度是 \(O(\sqrt n \log n\),所以总复杂度是 \(O(n\log^2n+q\sqrt n \log n)\)

代码:

#define mod (1ll<<31)
struct que{
	int n,m,a,tim;
	inline bool operator<(const que& T)const{
		return a<T.a;
	}
}q[100005];
int T;
int mu[5000005],pr[500005],cnt;
bool vis[5000005];
struct sigma{
	int id; ll val;
	inline bool operator<(const sigma& T)const{
		return val==T.val?id<T.id:val<T.val;
	}
}d[5000005];
int ans[100005];
struct BIT{
	int t[2000005]; int len;
	inline int lowbit(int x){
		return x&(-x);
	}
	inline void add(int x,int k){
		while(x<=len){
			t[x]+=k; 
			x+=lowbit(x);
		}
		return;
	}
	inline int query(int x){
		int ret=0;
		while(x){
			ret+=t[x]; 
			x-=lowbit(x);
		}
		return ret;
	}
}t;
void work1(int n){
	mu[1]=1; d[1].id=1;
	for(rg int i=2;i<=n;++i){
		d[i].id=i;
		if(!vis[i]){
			pr[++cnt]=i;
			mu[i]=-1;
		}
		for(rg int j=1;j<=cnt&&i*pr[j]<=n;++j){
			vis[i*pr[j]]=1;
			mu[i*pr[j]]=-mu[i];
			if(i%pr[j]==0){
				mu[i*pr[j]]=0;
				break;
			}
		}
	}
	for(rg int i=1;i<=n;++i){
		for(rg int j=1;i*j<=n;++j){
			d[i*j].val+=i;
		}
	}
	sort(d+1,d+1+n);
}
inline int work2(int n,int m){
	int ret=0;
	for(rg int l=1,r=0;l<=n;l=r+1){
		r=min(n/(n/l),m/(m/l));
		ret+=(t.query(r)-t.query(l-1))*(m/l)*(n/l);
	}
	return ret&(mod-1);
}
signed main(){
	T=read();
	work1(100001); t.len=100001;
	for(rg int i=1;i<=T;++i){
		q[i].n=read(); q[i].m=read(); q[i].a=read(); q[i].tim=i;
		if(q[i].n>q[i].m) swap(q[i].n,q[i].m);
	}
	sort(q+1,q+1+T);
	for(rg int i=1,j=1;i<=T;++i){
		while(j<=100001&&d[j].val<=q[i].a){
			for(rg int k=1;k*d[j].id<=100001;++k){
				t.add(k*d[j].id,d[j].val*mu[k]);
			}
			++j;
		}
		ans[q[i].tim]=work2(q[i].n,q[i].m);
	}
	for(rg int i=1;i<=T;++i){
		printf("%d\n",ans[i]);
	}
	return 0;
}

回顾一下,莫比乌斯反演主要用于干什么?

\[[]\implies\sum \]

它主要用于将条件转换为求和,柿子的推法非常灵活,也是最简单、最具有代表性的反演之一,所以大部分人(包括我)学习反演首先学的就是莫比乌斯反演。

另外莫比乌斯反演还有许多有趣的题目,这里只提供了 3 种最典型的例子,更多的题目感兴趣的读者可自行查阅相关资料(雾)(逐渐 lrj 化)。

基础习题(win10 很菜,更难的题目ta不会做):

P3455 [POI2007]ZAP-Queries

P2257 YY的GCD

P3312 [SDOI2014]数表

P3704 [SDOI2017]数字表格

P1829 [国家集训队]Crash的数字表格 / JZPTAB

P6222 「P6156 简单题」加强版


欧拉反演

其实我觉得欧拉反演这个名字挺莫名其妙的。

它不像莫比乌斯反演、二项式反演、子集反演、傅里叶变换有自己的能建立起两个函数的相互转换的反演定理(公式)。

所以我觉得欧拉反演是个不严谨的叫法,本质上还是莫比乌斯反演。

我觉得应该就叫“欧拉函数的一个性质”

但那么多人都这么叫,我也就顺带提一下。

还是先丢出一个结论:

\[\operatorname{id}=1\ast \varphi \]

why?

根据算术基本定理,令 \(n=\prod_{i=1}^{k}p_i^{c_i}\)

考虑对于每一个 \(p_i\) ,我们只要证明 \(p_i^{c_i}=\sum_{d|p_i^{c_i}}\varphi(d)\) ,就可以由 \(\operatorname{id}\)\(\varphi\) 的积性推出 \(n=\sum_{d|n}\varphi(d)\)

开始!

\[\sum_{d|p_i^{c_i}}\varphi(d)=\sum_{j=0}^{c_i}\varphi(p_i^j) \]

\(\varphi\) 的某性质:

\[\sum_{d|p_i^{c_i}}\varphi(d)=1+\sum_{j=1}^{c_i}(\varphi(p_i^j)-\varphi(p_i^{j-1})) \]

根据我们小学奥数的经验,把后面那一坨和式展开,前后相减抵消:

\[\sum_{d|p_i^{c_i}}\varphi(d)=1+(-1+p_i^{c_i}) \]

\[\sum_{d|p_i^{c_i}}\varphi(d)=p_i^{c_i} \]

证完啦!

EX:其实根据莫比乌斯反演定理,由 \(\operatorname{id}=1\ast \varphi\) 就可以得到:\(\varphi=\operatorname{id}\ast \mu\)

有什么用?


problem:

给定 \(n,m\),求:

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

solution:

这个柿子看上去很莫反。

确实莫反也能做,详情看能量采集的题解区,通过莫比乌斯反演也能艰难地做出来。

但有了我们上面这个结论了呢?

\[ans=\sum_{i=1}^n\sum_{j=1}^m \gcd(i,j) \]

\[ans=\sum_{i=1}^n\sum_{j=1}^m \sum_{d|i,d|j}\varphi(d) \]

套路,都是套路:

\[ans=\sum_{d=1}^{\min(n,m)}\varphi(d)\sum_{i=1}^n\sum_{j=1}^m [d|i,d|j] \]

\[ans=\sum_{d=1}^{\min(n,m)}\varphi(d)\lfloor\dfrac{n}{d}\rfloor\lfloor\dfrac{m}{d}\rfloor \]

快快乐乐提前筛出 \(\varphi\),然后 \(O(n)\) 求解,如果多组询问套个整除分块就行了。


总结

欧拉反演就没了?

确实没了,该讲的在莫反都讲过了。

欧反是用来干什么的?

\[value\to \sum \]

将求值转化为求和,运用场合与莫反基本一样,两者经常搭配出现。


二项式反演

其实和莫反一样都是容斥。


傅里叶变换(单位根反演)(DFT & IDFT)


子集反演(FWT & FMT)


EX:

亚线性复杂度的积性函数求和


杜教筛!

problem:

给定 \(n,m\),求 \(1\leq a\leq n\)\(1\leq b\leq m\)\(a,b\) 互质的有序对数。

\(1\leq n,m\leq 10^{12}\)

solution:

整除分块!

珂是 \(\mu\) 的预处理是 \(O(n)\) 的。

怎么办?


杜教筛用于求出一些积性函数的部分前缀和(不是全部,是 \(\sqrt n\) 个点值,和整除分块正好契合)。

优点:简单易懂,效率极高,常数极小,代码极短,只要能杜教筛,首选杜教筛,其它的都是浮云。

缺点:适用范围过窄,只能筛少数的几个函数,对目标函数关于狄利克雷卷积的一些性质有特殊要求。


首先,简单点,我们只考虑求出 \(sum\mu(n)=\sum_{i=1}^n\mu(i)\) 一个点值。

好像从普通和式的角度已经没有优化余地了呢。

但是考虑一下 \(\mu\) 卷上 \(1\) 后得到 \(\epsilon\) 这个奇怪的性质,\(1\)\(\epsilon\) 的前缀和都水爆了,能不能通过这两个东西推出 \(sum\mu\) 呢?


对于积性函数 \(f\),找到另一个积性函数 \(g\),考虑它们的狄利克雷卷积的前缀和:

\[\sum_{i=1}^nf(n)*g(n)=\sum_{i=1}^n\sum_{d|n}f(d)\times g(\dfrac{n}{d}) \]

和式的套路,交换求和顺序:

\[\sum_{i=1}^nf(n)*g(n)=\sum_{i=1}^ng(i)\sum_{d=1,i|d}^nf(\dfrac{d}{i}) \]

换元:

\[\sum_{i=1}^nf(n)*g(n)=\sum_{i=1}^ng(i)\sum_{d=1}^{\lfloor\frac{n}{i}\rfloor}f(d) \]

后面是啥?

\[\sum_{i=1}^nf(n)*g(n)=\sum_{i=1}^ng(i)\times sumf(\lfloor\frac{n}{i}\rfloor) \]

得到这个东西有什么用?我们是想求出 \(sumf(n)\),观察右面的柿子,当 \(i=1\) 时,\(\lfloor\dfrac{n}{i}\rfloor\) 取到 \(n\),即 \(sumf(\lfloor\frac{n}{i}\rfloor)\) 就是 \(sumf(n)\)

那么我们把这一项单独拎出来:

\[\sum_{i=1}^nf(n)*g(n)=\sum_{i=2}^ng(i)sumf(\lfloor\frac{n}{i}\rfloor)+g(1)\times sumf(n) \]

换一下顺序,就是杜教筛的套路柿子了:

\[g(1)\times sumf(n)=\sum_{i=1}^nf(n)*g(n)-\sum_{i=2}^ng(i)sumf(\lfloor\frac{n}{i}\rfloor) \]

\(\sum_{i=1}^nf(n)*g(n)\) 可以 快速求出的情况下,我们就可以递归求出 \(sumf\) 了。

时间复杂度?

发现是 \(O(\sum_{i=1}^{\sqrt n}\sqrt i+\sum_{i=1}^{\sqrt n}\sqrt \frac{n}{i})=O(\sum_{i=1}^{\sqrt n}\sqrt \frac{n}{i})\),对其积分:

\[=O(\int_{1}^{\sqrt n}\sqrt \frac{n}{x}\delta x)\approx O(n^{\frac{3}{4}}) \]

实际运用中则会先预处理前 \(n^{d}\) 项,则复杂度为:

\[=O(n^d+\int_{1}^{n^{1-d}}\sqrt \frac{n}{x}\delta x) \]

\(d=\frac{2}{3}\) 时最优为 \(O(n^{\frac{2}{3}})\)


Powerful Number 筛

\(\texttt{Powerful Number}\) 筛本质上是杜教筛 Pro,思想和杜教筛差不多(构造狄利克雷卷积前缀和),学过杜教筛之后就很好理解。

假设我们要求 \(f\) 的前缀和,构造 \(f=g\ast h\)

时间复杂度为 \(O(n^{\frac{2}{3}}+\sqrt nT(n))\)\(T(n)\) 表示求 \(h\) 的一项的复杂度)。


Min_25 筛!


卡常

posted @ 2022-02-09 15:38  Legitimity  阅读(149)  评论(0编辑  收藏  举报