积性函数
在信息学奥赛中,有时会遇到一些定义域在正整数域下的函数,即数论函数。积性函数作为一类特殊的数论函数,经常成为我们讨论的对象。在这一类问题中,选手们往往需要先进行一些推导,并选择合适的方法整理计算后的式子,这时就需要一些搞笑高效的算法来帮助我们完成最后的计算。
常见的积性函数
-
除数函数 \(\sigma_{k}(n)=\sum_{d|n}d^k\)
-
\(\text{Euler}\) 函数 \(\varphi(n)=\sum_{i=1}^n[\gcd(i,n)=1]\)
-
\(\text{M\"{o}bius}\) 函数 \(\mu(n)=\begin{cases}1&n=1\\(-1)^k&n为k个不同质数之积\\0&\text{otherwise}\end{cases}\)
常见的完全积性函数:
-
幂函数 \(\text{Id}_k(n)=n^k\),\(\text{Id}_1\) 简记为 \(\text{Id}\)
-
单位函数 \(\epsilon(n)=[n=1]\)
Dirichlet 卷积
定义 \(*\) 运算表示:
Dirichlet 卷积有以下性质:
-
交换律:\(f*g=g*f\)
-
结合率:\((f*g)*h=f*(g*h)\)
-
分配率:\(f*(g+h)=f*g+f*h\)
-
单位元:\(f*\epsilon=f\),其中 \(\epsilon(n)=[n=1]\)
-
若 \(f,g\) 都是积性函数,则 \(f*g\) 也是积性函数
证明是显然的,这里不放了。
常见的卷积有:
-
\(\mu * 1 = \epsilon\)
-
\(\varphi * \text{Id}=1\)
-
\(\varphi * 1 = \text{Id}\)
证明过程放在每个题里。
莫比乌斯函数
定义莫比乌斯函数 \(\mu(n)\)。设 \(n=\prod\limits_{i=1}^kp_i^{\alpha_i}\),有
可知这个函数是积性函数,于是可以线性筛求 \(\mu\)。代码如下:
void euler(int n)
{
mu[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!v[i]) p[++pcnt] = i, mu[i] = -1;
for (int j = 1; j <= pcnt && i * p[j] <= n; j++)
{
v[i * p[j]] = 1;
if (i % p[j] == 0) break;
mu[i * p[j]] = -mu[i];
}
}
}
莫比乌斯反演
如果两个数论函数 \(f,g\) 满足:
则它们也同时满足:
反之亦然,即 \(f=g*1\iff g=\mu*f\)。
\(\text{proof.}\)
左推右,考虑凑出 \(f*\mu\),所以对两边都卷上 \(\mu\),有
于是只要证 \(1*\mu=\epsilon\) 就行了。这个引理十分重要,这里证一下。
考虑利用算贡献的方法,考虑每个因数会选出多少个质因数,考虑这个数量的贡献求和,来改写式子左边有,
于是有 \(f*\mu=g*\epsilon=g\),充分性得证。
必要性只需要把两边都卷上 \(1\) 就行了。\(\text{Q.E.D.}\)
在基础应用中,最常用的是证明过程中顺手证的引理,但是正牌莫反会有更多的用处。但我们先不急着去做题,莫比乌斯反演还有一种非卷积形式:
设 \(f,g\) 为数论函数,\(t\) 为完全积性函数且 \(t(1)=1\),有
\(\text{proof.}\)
左推右,有
枚举 \(ki\),有
由引理,得
反之亦然。\(\text{Q.E.D.}\)
一些基础例题
1.GCD SUM
求
\(\text{sol.}\)
先证引理:\(\varphi(n)=\sum_{d|n}\mu(d)\frac{n}{d}\)。
然后考虑 \(\mu(d)\) 的贡献,有
故引理得证。这个引理也很常用。
其中第一行到第二行我们把 \(d\) 提到前面去,改枚举 \(i,j\) 为 \(\frac{i}{d},\frac{j}{d}\),把 \([\gcd(i,j)=d]\) 转化为 \(\gcd(\frac{i}{d},\frac{j}{d})=1\),就可以利用莫反了。所以第二步到第三步就是生套莫反公式,第三步到第四步是考虑 \(\mu(k)\) 的贡献,然后再改求和顺序。这样线性筛 \(\varphi\),求前缀和,然后整除分块就可以 \(O(n)\) 做了,瓶颈是线性筛。
请格外注意过程中对和式的处理。
2.Crash的数字表格 / JZPTAB
求
\(\text{sol.}\)
然后利用经典算贡献套路把 \(d\) 提出来,枚举 \(i,j\) 改为枚举 \(di,dj\) 来枚举 \(\gcd(i,j)\),不妨设 \(n\leq m\),有
由莫比乌斯反演公式,我们有 \(\sum_{d|n}\mu(d)=\epsilon(n)\),于是原式转化为
然后再利用枚举 \(\gcd\) 的套路,有
记 \(s(x)=\sum_{i=1}^x i\),于是有
把 \(s(\lfloor\frac{n}{dx}\rfloor)s(\lfloor\frac{m}{dx}\rfloor)\) 提前面,就有
然后预处理 \(b\mu(b)\) 的 Dirichlet 前缀和,然后整除分块就能做了。
3.约数个数和
设 \(d(x)\) 表示 \(x\) 的约数个数,求
\(\text{sol.}\)
先想着利用 \(d\) 的积性,把 \(d(ij)\) 转化为 \(\frac{d(i)d(j)}{d(\gcd(i,j))}\),发现推得
如果所求有取模,那直接预处理 \(sum_{i=1}^nd(i)\) 和 \(\sum_{i=1}^n\frac{1}{d(i)}\) 就可以做到 \(O(\sqrt{n})\) 了,但这个题没有取模的要求,考虑直接求 \(d(ij)\)。我们有引理:
\(\text{proof.}\) 不会,抄的题解,但感觉很有用,记一下以后常看看。
然后莫反的过程就比较平凡了。
加强一下:[SDOI2018] 旧试题
求
\(\text{sol.}\)
还不会
杜教筛
设 \(f\) 为数论函数,要求
考虑构造一个数论函数 \(g\),我们有恒等式
得到递归式
熟知 \(\lfloor\frac{n}{i}\rfloor\) 的取值为 \(O(\sqrt{n})\) 的,假如可以快速对 \((f*g)(i)\) 与 \(g(i)\) 的和,可以根据 \(\lfloor\frac{n}{i}\rfloor\) 的值进行数论分块,进行一遍求和的时间复杂度就是 \(O(\sqrt n)\),然后总的复杂度就是
(温情提示:前方积分预警)
后面一部分明显比前一部分大,所以考虑算后面的。
你可能说积分算大了,但你舍掉左边那一部分本来就算小了啊。
考虑能否优化这个过程,我们考虑预处理一部分,然后剩下部分直接调用算好的。我们设预处理了前 \(k\) 个 \(S\) 并假设预处理的复杂度为 \(O(n)\),那么复杂度就是
由均值不等式可知当 \(k\) 取 \(n^{\frac{2}{3}}\) 是复杂度最小,为 \(O(n^{\frac{2}{3}})\)。
例题:简单的数学题
求
\(\text{sol.}\)
利用莫反常见套路推出来
然后考虑算 \(S(n)=\sum_{i=1}^ni^2\varphi(i)\)。我们套用杜教筛板子
我们想到 \(\varphi\) 的常见卷积
于是令 \(g(x)=x^2\),有
然后就可以快速地进行杜教筛。