数论函数小结
数论函数小结
一些题外话
上了大学脑子根本转不动了啊
数论函数等内容在高中的信息学竞赛中就有很大占比,一脉相承的在 XCPC 系列竞赛中同样是相当重要的内容,可惜学来学去一直模棱两可,今天有总算有机会系统总结一下,顺便学一点新的东西好了。
【菲尔兹奖得主 Richard E. BORCHERDS】数论 Theory of numbers
推荐一点课程吧,有的一点感悟就是想要传播知识并不容易,Richard 的课程可以说通俗易懂了,没有过多的名词修饰,干净简洁,最重要的是知识的循序渐进,从简单的例子入手循序渐进的引入各种知识。很多教程或博客总是喜欢罗列抽象的数学公式,虽然强调了规范性但是也损失了不少可读性。
再次感慨学海无涯,仅仅是数论中的一块小小分支就已经有如此长的篇幅,学的越多会的越少
数论函数
首先我们称定义域为正整数域,陪域为复数域的函数被称为数论函数。数论函数之间的关系常常是研究的重点,我们不妨从几个常见的数论函数开始,逐步研究它们的性质。
- 除数函数 \(\sigma_k(n)\),表示 \(n\) 所有约数的 \(k\) 次幂之和。
- 欧拉函数 \(\varphi(n)\),表示不超过 \(n\) 的与 \(n\) 互质的正整数的个数。
- 莫比乌斯函数
\( \mu(n)= \begin{cases} 1, & n=1,\\[4pt] (-1)^k, & n=p_1p_2\cdots p_k\ \text{且}\ p_1,\dots,p_k\ \text{互不相同},\\[4pt] 0, & \text{否则}. \end{cases} \) - 幂函数 \(\text{id}_k(n)=n^k\)
- 单位函数
\( \epsilon(n)= \begin{cases} 1, &n=1\\[4pt] 0, & n>1 \end{cases} \) - 不同因子个数 \(\omega(n)\),\(n\) 中的不同质因子个数。
- 因子个数 \(\Omega(n)\),\(n\) 中的可重质因子个数。
- 黎曼zeta函数 \(\zeta(s)=\sum_{n=1}^{\infty}\frac{1}{n^s}, \qquad \Re(s)>1.\)
我们逐个研究他们的性质。
数论函数性质
我们先来看 \(\sigma_0(n)\),此时所有因子的次数均为 \(0\),因此相当于求 \(n\) 的约数个数。
| n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| \(\sigma_0(n)\) | 1 | 2 | 2 | 3 | 2 | 4 | 2 | 4 | 3 | 4 |
观察此表,我们会发现这并不是一个十分平滑的函数,利用简单的基本算数定理可以得到:
跟据乘法公式,我们可以得到 \(\sigma_0(n)=(a_1+1)(a_2+1)(a_3+1)\cdots(a_n+1)\),从这里就可以看出 \(\sigma_0(n)\) 是满足乘积性质的,对于相互不包含的质数因子集合数 \(a\) 和 \(b\)(即互质),我们会发现 \(\sigma_0(ab)=\sigma_0(a)\sigma_0(b)\),我们把这种性质称为积性。
而对于幂函数 \(\text{Id}_k(n)=n^k\),容易知道对于任意的 \(a\) 和 \(b\) 都满足 \(\text{Id}_k(ab)=\text{Id}_k(a)\text{Id}_k(b)\),我们把这种性质称之为严格积性。
对于不同质因子个数函数 \(\omega(n)\),我们采用同样的分析方法,可以得到对于互质的 \(a\) 和 \(b\) 有 \(\omega(ab)=\omega(a)+\omega(b)\),类似的这种性质被称为加性。
如果可重复统计质因子个数,类似的我们可以得到严格加性函数的定义,这里不再赘述。
积性函数是经常被研究的对象,对加性函数指数化可以得到积性函数,两者没有太大区别,因此我们接下来着重对积性函数进行讨论。
常见积性函数
除数函数 \(\sigma_k(n)\)
在前文我们已经研究了 \(\sigma_0(n)\) 积性,那么如何推展到更加一般的情况?以 \(\sigma_1(n)\) 为例:
其中根据算术基本定理:
我们采用一种十分经典的转换方法,利用乘法原理上式可以化成:
进而利用初等的等差数列公式换成更加一般的形式:
此时容易发现 \(\sigma_1(n)\) 同样满足乘积性质,类似的我们可以对质数因子的质数稍作修改,很容易归纳得到整个除数函数 \(\sigma_k(n)\) 为积性函数。
欧拉函数 \(\varphi(n)\)
欧拉函数表示小于 \(n\) 且与 \(n\) 互质的数的个数,一种可行的方法是利用容斥原理,逐步排除掉各种因子的影响,具体的:
同样利用类似的乘法原理可以得到:
这个形式指出欧拉函数同样满足积性函数性质。当然也可以反过来理解一下,\((1-\frac{1}{p})\) 可以理解成 \(n\) 挑选数字中与 \(p\) 互质的概率,最后乘积即为欧拉函数。
莫比乌斯函数 \(\mu(n)\)
莫比乌斯函数定义为
跟据定义很容易验证,\(\mu(n)\) 是积性函数,对于 \(\mu(n)\) 有如下的重要关系:
证明也很简单,我们可以用初等方法给出答案,稍后我们可以看到如何利用狄利克雷卷积简化这一过程。
从这个公式可以看出:莫比乌斯函数是常值函数 \(\text{1}\) 的狄利克雷逆。在莫比乌斯反演中有一个十分常见且重要应用:
这部分内容我们重点放在之后的莫比乌斯反演中讲解。
黎曼zeta函数 \(\zeta(s)\)
实际上 \(\zeta(x)\) 并不是数论函数,但是其在数论中有相当重要的地位。其定义十分简单:
利用欧拉乘积可以转换成积形式,进而在数论中实现对积性函数的级数变换。
前缀估计
对数论函数进行估计有十分重要的作用,尤其是在计算机领域,渐进的估计可以很好的为数论算法的复杂度分析提供参考。可以先来观察几类数论函数的小数据范围规律:
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
|---|---|---|---|---|---|---|---|---|---|---|
| \(\sigma_0(n)\) | 1 | 2 | 2 | 3 | 2 | 4 | 2 | 4 | 3 | 4 |
| \(\sigma_1(n)\) | 1 | 3 | 4 | 7 | 6 | 12 | 8 | 15 | 13 | 18 |
| \(\omega(n)\) | 0 | 1 | 1 | 1 | 1 | 2 | 1 | 1 | 1 | 2 |
| \(\varphi(n)\) | 1 | 1 | 2 | 2 | 4 | 2 | 6 | 4 | 6 | 4 |
可以看出不同函数都存在波动,那么如何估计 \(n\) 范围内的数论函数大小呢?一种常见的方法是对前缀和求平均值,我们首先以 \(\sigma_0(n)\) 为例:
在上式中计算不同数字的贡献,数字 \(k\) 贡献了大约 \(\frac{n}{k}\),这是因为在 \(n\) 中大约有 \(\frac{n}{k}\) 个数为 \(k\) 的倍数,因此上式可以近似的转换成:
这是常见的调和级数求和,我们知道它的近似是 \(\ln (n)\),因此我们得出估计:对于一个整数 \(n\),他的因子个数大约近似在 \(\log(n)\) 级别。
接下来我们看看对 \(\omega(n)\) 的近似。\(\omega(n)\) 指的是 \(n\) 中所包含不同质因子的种类,根据上文我们知道它是满足不完全加性的,同样的利用前缀和我们得到:
同样对贡献进行统计:每个质数 \(p\) 有 \(\frac{n}{p}\) 次贡献机会,因此此时同样可以得到贡献为:
这个问题可以引入梅滕斯定理解决,这个定理的证明是相当困难的,不过我们可以采用更加粗放的近似,这个结果大约是 \(\log \log (n)\),后文我们将看到这一证明。
欧拉乘积
在开始狄利克雷相关内容之前,必要的是补充一下欧拉乘积的知识。跟据基本算数定理,可以将任意正整数分解成若干质因子乘积的形式,因此我们对前文的黎曼zeta函数 \(\zeta(s)\) 可以得到这样一种结果:
进一步的,我们甚至可以推广,将上述过程中的 \(\zeta(s)\) 函数换成更加一般的函数,例如:
施以类似的过程,同样可以得到欧拉乘积形式:
如何研究 \(f\) 与 \(g\) 的关系?下文将介绍一种分非常强大的分析工具。
狄利克雷级数
回忆多项式中的生成函数,利用幂级数或者指数级数研究组合问题是一种相当强大的技术,那么在数论中有没有类似的工具呢?由此可以引入狄利克雷级数进行研究。
对于函数 \(f(n)\),我们定义 \(F(s)=\sum_{n=1}^\infty\frac{f(n)}{n^s}\),那么对于比较简单的几种情况,容易知道:
\(f(n)=n^k,F(s)=\zeta(s-k)\)
因此对于一般的多项式,其狄利克雷级数 \(F(n)\) 均可用 \(\zeta(s)\) 表示。接下来我们进一步研究:当 \(f(n)=\sigma_0(n)\) 时,有:
结合函数的积性以及一些初等方法,上述的推导给了我们不错的结果,接下来我们再来尝试一下 \(\sigma_1(n)\):
对于这个因子,考虑如何将其转换成更加熟悉的形式,也许用初等的等比数列性质一样可以进一步转化,不过这并非我们的本意。观察每个分式的形式,发现分子总是满足一种前缀求和的形式,因此可以用类似与欧拉乘积的方式转化:
因此回到原式可以得到 \(F(s)=\zeta(s)\zeta(s-1)\),这同样是一个相当漂亮的结果,利用类似的方法可以得到更高阶的除数函数狄利克雷级数结果:
一般的,我们继续来看这个形式:
继续的:
从之前的过程启发,我们计算如下的乘积:
这种关系给了我们一定的启发,似乎在狄利克雷级数中 \(\zeta(s)\) 函数扮演了 \(1\) 这个角色。利用这种关系,我们现在可以更加简便的得到 \(\sigma_k(n)\):
类似于普通生成函数,上式中的 * 符号被称为“狄利克雷卷积”,其一般形式可以被表示为:
此时我们称:
接下来我们对 \(\varphi(n)\) 同样应用狄利克雷级数分析,采用相同的方法得到欧拉乘积的各个因子:
因此原式可以化成:
到目前为止,我们已经发现狄利克雷级数与数论函数中存在一种对应关系,我们对已知的关系进行总结:
| dirichlet | Arithmetic |
|---|---|
| \(\zeta(s-k)\) | \(n^k\) |
| \(F\times G\) | \(f*g\) |
| \(F(s-k)\) | \(n^kf(n)\) |
| \(\zeta(s)\zeta(s-k)\) | \(\sigma_k\) |
| \(\frac{\zeta(s-1)}{\zeta(s)}\) | \(\varphi\) |
之后我们将会演示如何利用这些基本的形式得到一系列卷积关系。
代码实现也很简单。对于完全没有特殊性质的 \(f\) 和 \(g\),只能按照其定义进行计算,复杂度 \(\sum_{k}\frac{n}{k}\approx\Theta(n\log n)\)。
for(int k=1;k<=n;++k){
for(int d=1;k*d<=n;++d){
h[k*d]+=f[k]*g[d];
}
}
如果 \(g\) 为积性函数,考虑采用高维前缀和的思路,将每个质数 \(p^k\) 看成一个物品,在前 \(s\) 个质数构成的维度中做前缀积即可。
for(int i=1;i<=tot;++i){
for(int j=n/pri[i];j>=1;--j){
int t=pri[i];
for(int k=j*pri[i];k<=n;k*=pri[i]){
f[k]+=f[j]*g[t];
t*=pri[i];
}
}
}
实际上也可以理解为利用欧拉乘积加速这一过程,将 \(f\) 与 \(g\) 转换成狄利克雷级数的形式 \(F\) 与 \(G\),对 \(G\) 做欧拉乘积我们可以得到:
这样可实现更加优秀的 \(\Theta(n \log\log n)\),利用类似于埃氏筛的方法可以得到,至于复杂度证明会在之后的埃氏筛中简单提到。
for(int i=2;i<=n;++i){
if(vis[i]) continue;
for(int k=n/i*i;k;k-=i){
vis[k]=1;
int d=k;
while(1){
d/=i;
f[k]+=f[d]*g[k/d];
if(d%i) break;
}
}
}
特别的,当 \(g=\text{1}\) 时,即所谓的狄利克雷前缀和时,有:
for(int i=1;i<=tot;++i){
for(int j=n/pri[i];j>=1;--j){
int t=pri[i];
for(int k=j*pri[i];k<=n;k*=pri[i]){
f[k]+=f[j];
t*=pri[i];
}
}
}
因为系数为 \(1\),因此可以写成更加一般的形式:
for(int j=1;j<=tot;j++){
for(int i=1;i*pri[j]<=n;i++){
f[i*pri[j]]+=f[i];
}
}
而当 \(f\) 与 \(g\) 均为积性函数时,复杂度可以进一步优化为线性,这一点我们在之后的线性筛中详细讲解。
数论分块
为了更好的理解莫比乌斯反演在竞赛中的实际应用,先来学习一种基础的方法:数论分块。其可以快速计算类似:
观察上式可以发现,对于 \(n\) 个数的 \(\lfloor\frac{n}{i}\rfloor\) 有大量取值重复,因此可以按照 \(\lfloor\frac{n}{i}\rfloor\) 对整个数域分块,当左端点为 \(l\) 时,右端点为 \(\lfloor\frac{n}{\lfloor n/ l \rfloor}\rfloor\),如果我们能预处理或者在 \(\Theta(1)\) 的复杂度以内求出 \(f\) 区间和,那么可以优化掉 \(\Theta(\sqrt{n})\) 复杂度。
可以对数论分块做简单的扩展:
向上取整的数论分块
计算:
根据:\(\lceil\frac{n}{i}\rceil=\lfloor\frac{n-1}{i}\rfloor+1\)(自证不难),可以将其转换成向下取整的形式:
然后套用向下取整的数论分块即可。
多维数论分块
实际上之前的过程还可以被扩展为这样的形式:
很简单的,对于此时的左端点 \(l\),右端点选择最小的 \(\min\{\lfloor\frac{n_1}{\lfloor n_1/ l \rfloor}\rfloor\,\lfloor\frac{n_2}{\lfloor n_2/ l \rfloor}\rfloor\,\cdots,\lfloor\frac{n_m}{\lfloor n_m/ l \rfloor}\rfloor\}\),其他操作不变即可。
任意指数数论分块
取整运算
在数论分块中非常重要的是顶和底函数,即取整函数,这里从具体数学上总结一些基础的常见内容。
莫比乌斯反演
实际上,狄利克雷卷积运算具有一系列的完备的代数性质,使其构成封闭交换环,这种现象自然启示我们寻找环中的可逆元。简单来说,我们期望找到一种形式来表示与狄利克雷卷积正好相反的“除法运算”,这个形式就是莫比乌斯函数,其定义为:
观察 \(\mu(n)\) 的狄利克雷级数:
利用欧拉乘积:
这样我们可以得到一种非常优秀的工具,对卷积的反演提供了非常有力的工具。我们可以很轻松的得到狄利克雷前缀和的反演结果,具体来说:
更加工整的,可以写成好看的卷积形式:
更加一般的积性数论函数关系
以这样一个例子开篇:
我们考虑用初等方法证明:
如果我们用狄利克雷卷积相关的知识:
对应:
这是显然的。我们再来个例子。
欧拉反演指的是这样一类关系:
利用前文得到的狄利克雷卷积关系,写出在狄利克雷环下的级数形式:
这个恒等式一样然的,这样就远远简单于初等方法证明了上述的恒等式。
因此狄利克雷卷积为我们提供了一个很好的工具来寻找不同数论函数之间的关系,这在竞赛中同样是相当重要的,后文我们将看见这一技巧在各类亚线性筛法中的妙用。
小小总结
到目前为止我们应该已经得到了一个相比之前更加完整的 \(\text{dirichlet \& Arithmetic}\) 关系表:
| dirichlet | Arithmetic |
|---|---|
| \(\zeta(s)\) | \(1\) |
| \(1\) | \([n=1]\) |
| \(\frac{1}{\zeta(s)}\) | \(\mu\) |
| \(\zeta(s-k)\) | \(n^k\) |
| \(F\times G\) | \(f*g\) |
| \(F(s-k)\) | \(n^kf(n)\) |
| \(\zeta(s)\zeta(s-k)\) | \(\sigma_k\) |
| \(\frac{\zeta(s-1)}{\zeta(s)}\) | \(\varphi\) |
实际上很多狄利克雷级数知识相当深奥,不太适用于竞赛实际,这里不做探讨。
筛法
利用算法筛出质数被称之为筛法,但是因为质数的一系列特殊性质,很容易与积性函数建立联系,因而很多筛法可以用来加速求数论函数。
埃氏筛
埃筛是一种古老筛法,用所有已经筛出的素数的倍数标记合数:
template <int MAXN> vector<int> get_prim_bitset(){
int cnt(0);
static bitset<MAXN + 10> vis;
vector<int> prim;
vis[0] = vis[1] = 1;
for(int i = 2; i <= MAXN; ++i){
if(vis[i])
continue;
prim.emplace_back(i);
for(long long j = 1LL * i * i; j <= MAXN; j += i)
vis[j] = 1;
}
return prim;
}
如果利用 bitset 对标记数组进行优化,还可以进一步缩小常数,埃筛的复杂度为 \(\Theta(n\log\log n)\),接下来我们采用一种较为简单的方式渐进证明:
埃氏筛复杂度证明
(埃氏筛复杂度 \(O(n\log\log n)\) 只需要这个方向。)
引理 1:切比雪夫估计 \(\theta(x)=O(x)\)
记 \(\theta(x)=\sum_{p\le x}\ln p\)。
\(\binom{2m}{m}\) 被所有 \(m<p\le 2m\) 的素数整除,故
对区间 \((x/2^{k+1},\,x/2^k]\) 逐段累加:
引理 2:梅滕斯第一定理的上界
证明:由勒让德公式 \(\ln n!=\sum_{p\le n}\ln p\sum_{k\ge1}\lfloor n/p^k\rfloor\) 与斯特林公式 \(\ln n!=n\ln n-n+O(\ln n)\):
移项并代入引理 1 的 \(\theta(n)=O(n)\):
分部求和(Abel 求和)
记 \(A(t)=\sum_{p\le t}\frac{\ln p}{p}\le\ln t+C\),则
其中用了
故 \(\sum_{p\le x}\frac{1}{p}\le\ln\ln x+O(1)\),证毕。\(\blacksquare\)
备注
- 下界方向:由欧拉乘积
再展开 \(-\ln\left(1-\frac1p\right)=\frac1p+O\!\left(\frac{1}{p^2}\right)\)(\(\sum_{p}1/p^2<\zeta(2)=O(1)\)),即得 \(\sum_{p\le x}\frac1p\ge\ln\ln x-O(1)\)。上下界合起来:
- 精确常数:若要 \(\ln\ln x+M\)(\(M\approx0.2615\),Meissel–Mertens 常数),需要素数定理。PNT 等价于 \(\theta(x)\sim x\),此时引理 2 的不等号变为渐近等号,分部求和即给出常数 \(M\)。
区间筛
区间筛是为了解决某种区间素数相关的问题,对于这种问题,一个关键的观察是只用筛去 \(\sqrt{R}\) 以内的所有质因子,然后将质因子在区间内的倍数全部筛去即可。当然将下标平移即可避免区间偏置过大的问题。
因此区间筛同样可以筛出区间内的积性函数,对于每个数 \(i\) 可以利用质因子将积性函数转换为乘法形式,实现 \(\Omicron( n\log\log n)\) 复杂度。
实际上区间筛又称为“块筛”,对于极其庞大的上界范围内,想要求出积性函数在质数环上的某些状态,可以采用类似于分块的想法,分出不同的区间块分别应用区间筛,相当于时间换空间。
欧拉筛
埃氏筛法仍有优化空间,它会将一个合数重复多次标记,如果能让每个合数都只被标记一次,那么时间复杂度就可以降到 \(\Theta(n)\) 了。
vector<int> get_prim(int MAXN){
vector<int> spf(MAXN + 10), prim;
for(int i = 2; i <= MAXN; ++i){
if(!spf[i])
prim.emplace_back(i), spf[i] = i;
for(int j = 0; j < (int)prim.size() && prim[j] <= MAXN / i; ++j){
spf[prim[j] * i] = prim[j];
if(i % prim[j] == 0)
break;
}
}
return prim;
}
在欧拉筛中,一个相当重要的工具是对积性函数在不同质因子下的分类讨论,回顾欧拉筛诞生的历史,为了让每个合数被标记一次,我们处理除了所有当前数的最小质因子,即 spf 表,这个过程有很多良好的性质,我们尝试着用线性筛筛出一些常见的数论函数。
筛法求欧拉函数
观察线性筛的过程,设当前 \(n\) 最小的质因子为 \(p\),设 \(n^{\prime}=\frac{n}{p}\) 我们需要处理如下两个情况:
-
\(n^{\prime}\bmod{p}\ne 0\) 显然此时 \(n^{\prime}\perp p\),因此 \(\varphi(n)=\varphi(n^{\prime})\varphi(p)=\varphi(n^{\prime})(p-1)\).
-
\(n^{\prime}\bmod{p}=0\) 此时若 \(p^c\parallel n^{\prime}\),则
\[\begin{aligned} \varphi(n)&=\varphi\left(\frac{n^{\prime}}{p^c}\right)\varphi(p^{c+1})\\ &=\frac{\varphi(n^{\prime})}{\varphi(p^c)}\varphi(p^{c+1})\\ &=\frac{\varphi(n^{\prime})}{p^{c-1}(p-1)}p^{c}(p-1)\\ &=\varphi(n^{\prime})p\\ \end{aligned} \]
那么接下来只要简单改造一下欧拉筛的过程即可。
筛法求莫比乌斯函数
这个就更简单了,根据定义有:
其中 \(\mu(p)=-1\).
筛法求约数个数
根据简单的约数个数定理,我们知道约数个数等于所有质数的幂次的乘积,即:
利用和之前相同的分析流程可以得到:
根据上式,我们还需要记录每个数字的最小质因子的幂次 c[i],可以在上述过程中同时转移:
在质数上,\(c(p)=1\),\(\sigma_0(p)=2\).
筛法求约数和
前文我们也提到过:将 \(\sigma_1(n)\) 用欧拉乘积变成乘法形式有:
这样可以很简单的得到推导形式:
其中 \(g(n)\) 表示 \(n\) 的最小质因子 \(p\) 的 \(1+p+\cdots p^k\)。
一般积性函数筛法
根据前几次的示范,我们已经可以总结规律了,对于任何在质数处可以 \(\Theta(1)\) 求解的积性数论函数,都可以在 \(\Theta(n)\) 复杂度内求解,具体流程无非是考虑在最小质因子 \(p\) 与 \(n^{\prime}\) 是否整除的关系下,讨论数论函数的转移关系,可以用欧拉乘积将积性数论函数转变成乘法形式,对于不方便转变的,也可以直接讨论数论函数不同质因子的贡献。
杜教筛
PN 筛
\(\text{MIN}\_25\) 筛
洲阁筛
一些例题
感觉把这部分也放上来就太冗余了,那就另开一篇好了。

浙公网安备 33010602011771号