VII. 数论

前言

数论的知识点在OI中是较为成体系的。但这有时也限制了数论题目的出题方向,总有一种炒冷饭的感觉。
或许正是因此,近几年数论题目较为冷门。然而,系统的学习一些经典的知识(和套路),无疑是必要的。
我们顺便做一些约定:

  1. \(a,b,c,n,x,y,k\) 等等这种小写字母通常代表整数变量。
  2. \(f,g,h\) 一般表示函数,\(Sf\) 表示其前缀和。
  3. \(p\) 一般表示质数。\(n\) 常常表示问题规模。
  4. 如果一个变量没有范围,一般就认为它是任意的。

整除、约数、倍数

整除是数论中最基本的概念。
我们可以从如下事实中意识到它的强特殊性:

  1. \(n\) 的约数个数 \(d(n)=O(n^{1/3})\)。(我们采用了一个比较实用的估计)
  2. 通过约数和倍数的反演关系,我们知道 \(\sum_{i=1}^n d(i)=\sum_{i=1}^n \lfloor n/i\rfloor=O(n\log n)\)
  3. 两数的最大公约数有非常好的算法:欧几里得算法。

因此整除常常帮助我们减小检索的范围,进而优化题目中一些计算的复杂度。
关于整除,它有一些基本的性质,例如:\(ab|c\iff a|\dfrac{c}{\gcd(b,c)}\)。然而这些十分基础的性质过多过杂,我们会在下文指出对这些性质的理解方法。

素数

素数看上去是非常特殊的数。但是素数定理 \(\small{\pi(n)=O\left(\frac{n}{\log n}\right)}\) 告诉我们,素数是非常常见的数。
素数更重要的地位在如下定理中体现:
算术基本定理:任一正整数可以表示为若干素数的次幂乘积,并且这样的表示存在且唯一
这个定理的重要之处在于它提供的一个视角:将每个正整数写成素数的次幂的乘积,从而将正整数转化成由各指数构成的一个(无限维)向量。
例如:\(\small{12=2^2\times 3^1=(2,1,0,\ldots),100=2^2\times 3^0\times 5^2=(2,0,2,0,0\ldots),30=2^1\times 3^1\times 5^1=(1,1,1,0,0\ldots)}\)
存在且唯一保证了这是一个一一对应。于是,我们可以这样看待一些运算和关系:

  1. 乘/除法:向量加/减法。
  2. \(\gcd/\operatorname{lcm}\):向量各维取 \(\min/\max\)
  3. \(a\) 整除 \(b\)\(a\) 的各维 \(\le b\) 的各维。即偏序关系。

在此视角下,这些运算和关系的各维是独立的,因此我们可以在每一维分别考虑这些关系,能非常容易的说明数不清的结论。
如:\(\gcd(a,b)\operatorname{lcm}(a,b)=ab\)。当我们只在一维考虑这个关系,那就是说考虑 \(p^{\min(c_a,c_b)}\times p^{\max(c_a,c_b)}=p^{c_a}\times p^{c_b}\)
应用起刚刚的“向量”视角,就变成了 \(\min(c_a,c_b)+\max(c_a,c_b)=c_a+c_b\),是显然的。
再如,前文提到的结论 \(ab|c\iff a|\dfrac{c}{\gcd(b,c)}\)。在向量视角下变为 \(c_a+c_b\le c_c\iff c_a\le c_c-\min(c_b,c_c)=\max(c_c-c_b,0)\),也是显然成立的。
这个视角在OI的很多整除问题中十分好用。在文章的最后(注记1)中,我们给出了一些有用的关于整除的结论,读者可以尝试看看在上述视角下,这些结论的形式。

同余

同余可以看成整除自然的扩展。如果只有整除关系,那它在应对加法的时候就立刻茫然无措了。虽然也有一些好的结论(如更相减损术),但终究显得无力。
同余的概念一出现,整除就变成了同余的特殊情况。但相对的,同余也失去了整除的一些特殊性。于是,研究同余和研究整除的方法常常显得很不同。
我们先来看几个经典问题,进而提出一些同余系下的结论。

不定方程

这或许并不在“同余”这个大前提下,不过我们还是选择此时提出这个十分基本的问题:
关于 \(x,y\) 的不定方程 \(ax+by=c\) 的解是什么?
裴蜀定理和扩展欧几里得算法合力给出了这个问题的近乎完美的答案。内容不再赘述,我们现在只关心一般情况下解的结构:
\(\gcd(a,b)=d\),特解为 \((x_0,y_0)\),解集 \(\{(x,y)|ax+by=c\}=\{(x_0+k(b/d),y_0-k(a/d))|k\in \mathbf{Z}\}\)
看起来这个问题已经被研究透彻了。然而,没有用武之地的话,再强大的工具也是无用的。下文我们会展现它的更多应用实例。

同余系和环

同余系可以看成一个环,这个视角是以加法为中心的。
我们考虑一个组合问题:如果一个棋子,在长为 \(n\) 的环上每次都向后走 \(x\) 步,那么被它所遍历的位置是哪些?
即,集合 \(\{(start+kx)\bmod n)|k\in \mathbf{Z}\}\) 是什么样子的?
观察同余方程 \(xk+n\lambda=i\),我们发现 \(\{kx\bmod n\}=\{k\gcd(n,x)|k\in [0,n/\gcd(n,x))\}\)
这个问题可以看成不定方程的一个推论,我们会意识到它是一个非常常见的结构。

逆元

加减法、乘法都被自然的保留在同余系中,但是除法却成为了必然丢失的一个功能。
于是我们关心:何时才能做除法?准确的说,何时能让除法的结果存在且唯一?
巧妙而有用的方法是用乘法来做除法。于是我们的问题变为对 \(a\) 找到 \(x\) 使 \(ax\equiv 1\pmod n\)
转化成不定方程问题:\(ax+ny=1\)。我们立刻得到逆元存在条件 \(\gcd(a,n)=1\)
我们立刻知道:0在任何时候都是没有逆元的;模素数同余系下除了0都是有逆元的。这指出了我们计算时需要注意的关键。

一元一次同余方程

\(ax\equiv b\mod n\)。上面的经验告诉我们:考虑不定方程 \(ax+ny=b\)
由不定方程的解集,答案是 \(\{x_0+k(n/\gcd(a,n))\}\)。(只关心 \(x\) 的解集)
熟悉了模 \(n\) 同余和 \(+kn|k\in \mathbf{Z}\) 的关系,我们知道,这就相当于 \(x\equiv x_0\pmod{n/\gcd(a,n)}\)

一元线性同余方程组(模数互质)

中国剩余定理解决了这个问题。其构造性思想与拉格朗日插值如出一辙。
最重要的地位是:它指出了模数互质下解的唯一存在性
这使得它可以做到用几个较小的模意义下数字表示一个较大的数。使用Garner算法可以避免此时可能会出现的整型溢出问题。
同时,类似算术基本定理,我们有时可以将一个可能非常大的数字作为一个各维独立的向量考虑。

阶、原根、离散对数

既然我们研究过了一个数的倍数对同余系的遍历(上文“同余系和环”),现在不妨考虑一个数的次幂对同余系的遍历。
重点在于回到单位元(1)的时刻。欧拉定理(及其特殊情况,费马小定理)指出了一定回到单位元的一个次幂。于是它常用于求逆元、对指数取模。
然而我们还不满足,因为这个次幂不一定是最小的回到单位元的次幂。于是阶的概念产生了。
相应的,能遍历所有数(除去0)的数——原根也成了重要的研究对象。有了原根,离散对数应运而生,而所有数在取对数后,乘法(次幂)的遍历结构就变成了加法(倍数)的遍历结构。
于是,虽然我们没有得到一个很好的封闭形式,但如果已经有了原根和离散对数,弄清我们想知道的问题并不太难。
求解离散对数的传统方法是BSGS,它的思想可以在这种环形结构上做一些很一般的问题。
后来学习循环群的时候,理解这里给我提供了很多便利。

组合数取模

Lucas定理和Kummer定理给出了组合数取模时的一些优秀结论。
这除了能帮我们计算组合数外,还能配合数位dp做一些奇怪的计数问题。

“整除”、数论分块、整除集合

“整除”在此处指 \(a\oplus b=\lfloor a/b\rfloor\) 这个运算。下文中,我们不再为它和上文中的整除做区分,希望读者根据语境自行判断。
关于整除,有一个令人惊讶的性质:\(\lfloor \lfloor a/b\rfloor /c\rfloor=\lfloor a/bc\rfloor\)
于是,我们得到一个常用的工具:
数论分块:集合 \(\{\lfloor n/i\rfloor|i\in[1,n]\}\) 的大小为 \(\Theta(\sqrt n)\)。进一步的,其等于 \(\{1,2,\ldots \lfloor\sqrt n\rfloor,\lfloor n/\lfloor\sqrt n\rfloor\rfloor,\ldots \lfloor n/2\rfloor,\lfloor n/1\rfloor\}\)。我们将这个集合称为 \(n\) 的整除集合。
这个集合有良好的封闭性:其中的数做整除运算的结果仍在集合内。
于是,对于一些形如 \(f(n)=\sum f(\lfloor n/i\rfloor)g(i)\) 的递推式求单项时,我们只需要使用整除集合内的位置。
在数论筛法中,我们能看到它发挥的威力。

数论函数、积性函数、狄利克雷卷积系统、贝尔级数

我们将从一个代数化的角度看待数论函数。
积性函数是非常特殊的一类函数,关于它们我们已经得到了许多神奇的结论。
从积性函数的角度,联系算术基本定理,质因子分解后各维独立的性质显得更加有用。
于是我们自然地将积性函数在某个质数的次幂位置的取值提取出来,得到一个数列,这就是贝尔级数。
因为变成了各元独立的生成函数,写出贝尔级数能更容易的发现各种卷积关系。文章的最后(注记2),我们列举了一些常见积性函数的贝尔级数。

数论筛法(积性函数前缀和)

这部分可能是狄利克雷卷积系统在OI中最重要的成果。
我们定义块筛:对于一个给定的 \(N\) 和一个数论函数,计算这函数在 \(N\) 的整除集合位置的前缀和,称作对这函数完成块筛。
接下来我们描述几种具体的筛法,及其使用方式、条件和其能力范围。它们的名字有的是我瞎取的,有的是大家瞎取的
默认下文提到的数论函数可以 \(O(n)\) 求前 \(n\) 项的值,求质数次幂位置的值容易。有时涉及狄利克雷卷积可能会带上 \(\log\) 因子。

数论分块筛

对于数论函数 \(h=f*g\),有 \(Sh(n)=\sum_{1\le i\le n}f(i)Sg(\lfloor n/i\rfloor)\)
若已完成 \(f,g\) 的块筛,则可以在 \(O(\sqrt n)\) 的时间内求单个 \(Sh(n)\),在 \(O(n^{2/3})\) 的时间内对 \(h\) 完成块筛。

杜教筛

对于数论函数 \(h=f*g\),有 \(Sf(n)g(1)=Sh(n)-\sum_{2\le i\le n}g(i)Sf(\lfloor n/i\rfloor)\)
若已完成 \(g,h\) 的块筛,则可以在 \(O(n^{2/3})\) 的时间内对 \(f\) 完成块筛。
配合“数论分块筛”,我们得到:若已完成 \(f,g\) 的块筛,则 \(f*g,f/g\) 的块筛可以在 \(O(n^{2/3})\) 的时间内完成。
于是,利用贝尔级数构造卷积式,我们已经能筛出一大类数论函数。

Powerful Numbers 筛法(PN筛)

对于积性函数 \(f,g\),若 \(g\) 已完成块筛且 \(f(p)=g(p)\),则可以在 \(O(\sqrt n)\) 的时间内求单个 \(Sf(n)\),在 \(O(n^{2/3})\) 的时间内对 \(f\) 完成块筛。
这允许我们将一个神奇的积性函数的块筛问题转化成我们熟知的积性函数。command_block对它进行了一些推广,可以在一些问题上做到更低的复杂度、指出了给定 \(f\) 构造 \(g\) 的一些方法。

洲阁筛 & min_25 筛

对于积性函数 \(f\),若能找到完全积性函数 \(g\) 使得 \(f(p)=g(p)\),且 \(g\) 能完成块筛,那么能在 \(O\left(\dfrac{n^{0.75}}{\log n}\right)\) 的时间完成对 \(f\) 的块筛。
事实上,上述要求可以进一步降低。注意到构造 \(g\) 的目的仅仅是求出 \(f\) 在整除集合位置的前缀和中的素数部分,因此利用线性性将 \(f(p)\) 分解成若干函数的和也是可以的。
常见的情形是 \(f(p)\) 是关于 \(p\) 的常数次多项式。
min_25 筛可以看成洲阁筛的变种,它在求单个前缀和的时候效率更有优势。
这无疑是各种筛法中相对没有被完全发掘,且最灵活多变的一种。因此它的能力其实远不止描述的这些。稍加变形和拓展就能解决一些甚至不是积性函数求和的问题。
例如:用 min_25 筛求 \(f_k(n)=\sum_{1\le x\le n}[\omega(x)=k]\)

特殊算法

Miller Rabin & Pollard Rho

素数判定算法和质因子分解算法。二者都有随机化成分,因此常常出现一些玄学问题。比如我的PR经常分解不出来,运行速度远慢于四分之一次方

类欧几里得 & 万能欧几里得算法

经典的,二者可以解决二维平面上,一条直线下的整点统计问题。
万能欧几里得有很好的扩展性,能解决一些更一般的问题。比如将同余化为整除 \(a\bmod b=a-\lfloor a/b\rfloor b\) 后算一些神秘妙妙玩意。
谈起类欧几里得,其得名仅仅是源于递归过程与欧几里得算法相同。所以事实上有一大类奇怪的递归算法都可归入类欧

后记

限于NOI复习的实用性要求,还有一些足以说道的内容完全没有提及,如:莫反+推式子的题目;连分数相关;更快的质因子分解和离散对数算法……
以目前所见,在OI中的数论远没有数学中那么多变和困难。因此,掌握必要的知识就是我们的主要目标。

注记1

\[a|\gcd(b,c)\iff a|b\land a|c \]

\[a|bc\iff (a/\gcd(a,b))|c \]

注记2

\[\epsilon(n):1 \]

\[1(n):\dfrac{1}{1-x} \]

\[\mu(n):1-x \]

\[\mu^2(n):1+x \]

\[2^{\omega(n)}:\dfrac{1+x}{1-x} \]

\[id_k(n):\dfrac{1}{1-p^kx} \]

\[\sigma_k(n):\dfrac{1}{(1-p^kx)(1-x)},d(n)=\sigma_0(n) \]

\[J_k(n):\dfrac{1-x}{1-p^kx},\varphi(n)=J_1(n) \]

posted @ 2022-07-22 17:51  秋叶冬雪  阅读(319)  评论(2编辑  收藏  举报