数论入门笔记

公式较多,渲染可能较慢,正常现象(

这个憨批将近一年没摸数论知识了,于是重新学习了一遍。为了防止学习第三遍,所以打算写个东西记录一下这次我复习到的(很小一部分)数论知识。

因为我的数论知识非常垃圾,所以出错是很正常的,直接跟我对线即可,我会改的TAT

预计会有这些内容:

如果看到有 \(p,a,m\)​ 无端出现且没有定义,则默认定义为 \(n=\prod_{i\le m} p_i^{a_i}\)​,其中 \(a_i\neq0\)​。

莫比乌斯反演

虽然大家都会,还是丢一下莫比乌斯函数 \(\mu\) 的定义。设 \(n=\prod_{i\le m} p_i^{a_i}\),其中 \(a_i\neq0\)

\[\mu(n)=\begin{cases}0&\max a\ge2\\(-1)^m&\max a\le1\end{cases} \]

莫反的两大形式:

\[f(n)=\sum_{d|n}g(d)\Leftrightarrow g(n)=\sum_{d|n}\mu(\frac nd)f(d)\\ f(n)=\sum_{n|d}g(d)\Leftrightarrow g(n)=\sum_{n|d}\mu(\frac dn)f(d)\\ \]

证明:

(形式一)

\[\sum_{d|n}\mu(\frac nd)f(d)=\sum_{d|n}\mu(\frac nd)\sum_{p|d}g(p)=\sum_{p|n}g(p)\sum_{d|\frac np}\mu(d) \]

考虑 \(S(n)=\sum_{d|n}\mu(d)\) 的值:假设 \(n=\prod_{i\le m} p_i^{a_i}\)\(a_i\neq0\)),\(S(n)= \sum_k\binom m{2k}-\sum_k\binom m{2k+1}=[m=0]=[n=1]\)。因此有

\[\sum_{d|n}\mu(\frac nd)f(d)=\sum_{p|n}g(p)\sum_{d|\frac np}\mu(d)=\sum_{p|n}g(p)[\frac np=1]=g(n) \]

证毕。

(形式二)

\[\sum_{n|d}\mu(\frac dn)f(d)=\sum_{n|d}\mu(\frac dn)\sum_{d|p}g(p)=\sum_{n|p}g(p)\sum_{d|\frac pn}\mu(d)=\sum_{n|p}g(p)[\frac pn=1]=g(n) \]

证毕。

杜教筛

是一种亚线性筛法,可以做到积性函数求前缀和,但是使用难度不低。

先扔一些前置的东西:

狄利克雷卷积

定义两数论函数的狄利克雷卷积 \((f*g)(n)=\sum_{d|n}f(d)g(\frac nd)\)

狄利克雷卷积有交换律、结合律与对加法的分配律。证明可以直接把卷积的定义式写出来,对应项对照一下就行了。

积性函数

对于两数 \(p\perp q\),满足 \(f(p)f(q)=f(pq)\) 的函数是积性函数。对于任意两数都有 \(f(p)f(q)=f(pq)\) 的函数是完全积性函数。

积性函数满足性质:积性函数 * 积性函数 = 积性函数。证明也是直接展开写一写就行了。

常见的积性函数:

  • 元函数 \(\epsilon\)\(\epsilon(n)=[n=1]\)。(完全积性)
  • 恒等函数 \(I\)\(I(n)=1\)。(完全积性)
  • 单位函数 \(id\)\(id(n)=n\)。(完全积性)
  • 莫比乌斯函数 \(\mu\)
  • 欧拉函数 \(\phi\)\(\phi(n)=\sum_{i=1}^n[i\perp n]\)
  • 约数个数 \(d\)\(d(n)=\sum_{i=1}^n[i\ |\ n]\)
  • 约数和 \(\sigma\)\(\sigma(n)=\sum_{i=1}^ni\cdot[i\ |\ n]\)

这些积性函数又有一些性质:

  1. 对于任意 \(f\)\(f*\epsilon=f\)
  2. \(\mu * I=\epsilon\)
  3. \(\phi*I=id\)
  4. \(\frac{\phi(n)}n=\sum_{d|n}\frac{\mu(d)}d\)

证明:

2 证过了。

3:众所周知 \(\phi(n)=\prod_{i=1}^m p_i^{a_i-1}(p_i-1)\),所以有

\[\begin{aligned} \sum_{d|n}\phi(d)&=\sum_{i_1=0}^{a_1}\sum_{i_2=0}^{a_2}\cdots\sum_{i_m=0}^{a_m}\phi(p_1^{i_1}p_2^{i_2}\cdots p_m^{i_m})\\ &=(1+(p_1-1)+(p_1^2-p_1)+\cdots+(p_1^{a_1}-p_1^{a_1-1}))\sum_{i_2=0}^{a_2}\cdots\sum_{i_m=0}^{a_m}\phi(p_2^{i_2}\cdots p_m^{i_m})\\ &=p_1^{a_1}\sum_{i_2=0}^{a_2}\cdots\sum_{i_m=0}^{a_m}\phi(p_2^{i_2}\cdots p_m^{i_m})\\&=\cdots\\ &=p_1^{a_1}p_2^{a_2}\cdots p_m^{a_m}\\ &=n \end{aligned} \]

4:将 3 等式两边卷上一个 \(\mu\),则有

\[\phi*I*\mu=id*\mu\\ \phi*\epsilon=id*\mu\\ \phi(n)=\sum_{d|n}\mu(d)\cdot\frac nd\\ \frac{\phi(n)}n=\sum_{d|n}\frac {\mu(d)}d\\ \]

杜教筛

搞了那么多,跟杜教筛有啥关系呢(

假设我们想求一个积性函数 \(f\) 的前缀和 \(S(n)=\sum_{i=1}^nf(i)\)

我们不妨找另一个积性函数 \(g\),使得 \(f*g\) 是一个很优美的积性函数。我们可以得出:

\[\sum_{i\le n}(f*g)(i)=\sum_{i\le n}\sum_{d|i}f(d)g(\frac id)=\sum_{i\le n}g(i)\sum_{j\le\lfloor\frac ni\rfloor} f(j)=\sum_{i\le n}g(i)S(\lfloor\frac ni\rfloor) \]

因为我们想求 \(S(n)\),所以我们可以带 \(S(n)\) 的一项提出来。

\[g(1)S(n)=\sum_{i\le n}(f*g)(i)-\sum_{2\le i\le n}g(i)S(\lfloor\frac ni\rfloor) \]

剩下的 \(S\) 递归往下做即可。

一般做杜教筛的时候都会加记忆化(不然时间会假),还会先用线性筛预处理出 \(\sqrt n\) 范围内的 \(S\)。时间复杂度 \(O(n^{2/3})\),但是我不知道怎么证。

之所以说杜教筛很难用,是因为需要构造出一个 \(g\) 才能使用杜教筛,而这个构造过程可能不太好想。

举个例子:求 \(S(n)=\sum_{i=1}^n i{\mu(i)}\)

为了消掉 \(i\)​​,我们不妨令 \(g=id\)​​,这样 \((f*g)=(id\cdot\mu)*id=id\cdot\epsilon\)​​​​。然后套上面公式即可。上面那一块证明的很多性质可以用来构造另一个积性函数。注意狄利克雷卷积对点积没有结合律。

min_25 筛

声明:此版块下的所有 \(p\) 默认为质数。定义 \(lpf(i)\)\(i\) 的最小质因数。

这个筛比较强,可以解决一些杜教筛解决不了的问题,而且不需要构造,是我这种无脑选手的不二之选。

假设我们想求 \(S(n)=\sum_{i\le n}f(i)\)

min_25 筛适用于一些积性函数 \(f\),其中 \(f(p)\) 可以用多项式表示,且 \(f(p^k)\) 很好求值。

min_25 筛的主要思想是先把 \(f\) 看成完全积性函数 \(g\),其中 \(g(p)=f(p)\)\(g(n)=\prod_if(p_i)^{a_i}\)。这也就是为什么要求 \(f(p)\) 可以用多项式表示的原因:多项式可以被拆成单项式,而对单项式而言计算 \(g\) 是容易的。

但是我们把积性函数当成完全积性来算肯定是有错的,具体来说,在 \(x\not\in prime\) 的时候会有错。我们先考虑算出质数部分的和。

我们定义 \(G(i,j)=\sum_{i\le n} g(i)[i \in prime \lor lpf(i)>p_j]\),其中 \(p_j\) 是第 \(j\) 个质数。

\(G\) 的初值很显然,\(G(i,0)=\sum_{i\le n} g(i)\),而一般 \(g\) 的前缀和是好求的。

可以发现 \(G(i,|P|)=\sum_{i\le n} g(i)[i \in prime]\),因此我们考虑将 \(j\) 从小到大递推。

考虑 \(G(i,j-1)\)\(G(i,j)\) 多了些什么。我们发现 \(G(i,j-1)-G(i,j)=\sum_{x\le i}g(x)[x\not\in prime\land lpf(x)=p_j]\)

\({p_j}^2>i\) 时,\(G(i,j-1)-G(i,j)=0\)

\({p_j}^2\le i\) 时,\(G(i,j-1)-G(i,j)=g(p_j)(G(\lfloor\frac i {p_j}\rfloor,j-1)-\sum_{k=1}^{j-1}g(p_k))\)。之所以要减那一坨是因为 \(G\) 里面还包含了质数,但是算了 \(< p_j\) 的质数的贡献会导致我们乘出来的数的最小质因数不是 \(p_j\),因此要把它挖掉。


这样我们就可以递推求出 \(G(i,|P|)\) 了,但是我们还需要合数部分的值,于是我们再定义一个 \(F(i,j)=\sum_{i\le n} f(i)[i \in prime \lor lpf(i)>p_j]\),不难发现答案就是 \(F(n,0)+f(1)\)(1 没算)。

初值也是好得到的,\(F(i,|P|)=G(i,|P|)\)

于是我们再考虑将 \(j\) 从大到小递推。

考虑 \(F(i,j-1)\)\(F(i,j)\) 多了些什么。我们发现 \(F(i,j-1)-F(i,j)=\sum_{x\le i}f(x)[x\not\in prime\land lpf(x)=p_j]\)

但是因为 \(f\)​ 不是完全积性,所以我们不能直接向之前一样乘,还得枚举一个指数。

这里定义一个函数 \(sp(x)=\sum_{i\le x}f(p_i)\)​,这个可以线性筛求出来,因为我们只用得到 \(\le\sqrt n\)​ 的质数。​

具体而言,\(F(i,j-1)-F(i,j)=\sum_{e,p_j^{e}\le i}f(p_j^e)(F(\lfloor\frac i {p_j^e}\rfloor,j)-sp(j))+\sum_{e\ge2,p_j^{e}\le i}f(p_j^e)\)

于是快乐递推就行了。

时间复杂度是 \(O(\frac{n^{0.75}}{\log n})\),据说 min_26 筛可以做到 \(O(n^{2/3})\),但是跑起来差不多,我也不会。


powerful number 筛我不太会,但我在翻 min_25 筛题解的评论区的时候找到了这样一条评论:

所以大家可以问 hs。

二次剩余

一个数 \(a\) 是模 \(p\) 意义下的二次剩余,当且仅当存在数 \(x\)​ 使得 \(x^2\equiv a\pmod p\)

这里只讨论 \(p\)​ 是奇质数的二次剩余,因为其他情况我不会。

先扔一些有用的性质。以下性质均不考虑 0。

性质

  1. \(a^{\frac{p-1}2}\equiv1\pmod p\)​ 或 \(a^{\frac{p-1}2}\equiv-1\pmod p\)

由费马小定理,显然。注意我们排除了 0 的情况。

  1. \(a\)​ 是二次剩余当且仅当 \(a^{\frac{p-1}2}\equiv1\pmod p\)​,否则 \(a^{\frac{p-1}2}\equiv-1\pmod p\)​。

因为 \(p\) 是奇质数,所以 \(p\) 存在原根,设原根之一为 \(\phi\),则有 \(a^{\frac{p-1}2}\equiv\phi^{b\frac{p-1}2}\equiv1\pmod p\)​,可得 \(b\) 是偶数。

所以 \((\phi^{b/2})^2\equiv\phi^{b}\equiv a\pmod p\)​,\(a\)​​​ 是二次剩余,必要性得证。

\(a\) 是二次剩余,设 \(a\equiv x^2\),则 \(a^{\frac{p-1}2}\equiv x^{p-1}\equiv1\),充分性得证。

又因为性质 1,所以 \(a\)​ 不是二次剩余 $\Leftrightarrow $​ \(a^{\frac{p-1}2}\equiv-1\pmod p\)​​。​

这玩意又被叫做欧拉判别准则,还有个勒让德符号可以方便的表示这个式子:

\[\left(\dfrac np\right)=n^{^{\frac{p-1}2}}\bmod p\equiv\begin{cases}1&p\nmid n\land n\text{是二次剩余}\\-1&p\nmid n\land n\text{不是二次剩余}\\0&p\mid n\end{cases} \]

  1. \([1,{p-1}]\)​ 中,二次剩余和非二次剩余各有 \(\frac{p-1}2\)​ 个。

显然 \((p-x)^2\equiv x^2\),因此我们只需证明 \(x^2\bmod p\) 两两不同就能说明有 \(\frac{p-1}2\) 个二次剩余。

假设 \(x^2\equiv y^2\)\((x-y)(x+y)\equiv0\)

\(x+y\in[2,p-1]\),因此 \(x=y\)。得证。

Cipolla 算法

那如果我们现在拿到一个方程 \(x^2\equiv n\pmod p\),咋解呢?

我们先随机一个数 \(a\)​​​,使得 \(a^2-n\)​​​ 不是二次剩余。类似复数,我们利用 \(i\)​​ 扩一个域,其中 \(i^2=a^2-n\)​​,我们断言解是 \((a+i)^{\frac{p+1}2}\) 和它的相反数​。

证明:

\[(a+i)^{p+1}\equiv(a+i)(a+i)^p\equiv(a+i)(a^p+i^p)\equiv(a+i)(a-i)\equiv a^2-i^2\equiv n \]

第三个同余:\(a^p\equiv a^{p-1}a\equiv a,i^p\equiv i^{p-1}i\equiv-i\)。注意因为 \(i^2\) 不是二次剩余,所以 \((i^2)^{\frac{p-1}2}\equiv i^{p-1}\equiv-1\)

现在我们唯一的问题就是,\((a+i)^{\frac{p+1}2}\) 的虚部会不会非零?

假设 \((a+i)^{\frac{p+1}2}\equiv A+Bi\),则 \((a+i)^{p+1}\equiv A^2+B^2(a^2-n)+2ABi\equiv n\) ,所以 \(2AB\equiv0\)

\(A\equiv 0\),有 \(B^2(a^2-n)\equiv n\),而 \((B^2(a^2-n))^{\frac{p-1}2}\equiv B^{p-1}(a^2-n)^{\frac{p-1}2}\equiv-1\),而因为 \(n\) 是二次剩余,有 \(n^{\frac{p-1}2}\equiv1\),矛盾。所以 \(A\not\equiv0\),则 \(B\equiv0\)

exBSGS

普通的 BSGS 只能做底数模数互质的问题,但是可能会有憨批出题人出成非质模数,这时候就只能用 exBSGS了,,,

但是正规的 exBSGS 实在是太麻烦了,所以我乱搞了一个奇怪的算法(

还是和正常的 BSGS 一样,先预处理出 \(a^{x\sqrt{mod}}\)​,但是注意这里每个值的出现次数要记录最小和次小,因为两个不互质的值取模之后的结果是一个 ρ 形。

然后再枚举每个 \(a^y\),查询有没有 \(x\) 满足 \(a^{x\sqrt{mod}}\equiv ba^y\)。但是因为底数模数并不互质,所以 \(a\) 没有逆元,即 \(a^{x\sqrt{mod}-y}\equiv b\) 并不一定成立,所以需要写个快速幂验证一下。然后就行了。

这玩意具体有没有正确性我也不知道(),但是把模板题过了,应该问题不大(

万能欧几里得算法

这位更是重量级。

万能欧几里得算法是用来解决一系列与 \(\lfloor\dfrac{ax+b}c\rfloor\)​​ 有关的式子,要求满足操作(值)可以合并。

其主要思想是观察直线 \(y=\frac{ax+b}c\)​ 在一象限的图像:

每当其碰到一条竖线(\(x=a(a>0)\))时记录一个操作 \(R\),碰到一条横线(\(y=a(a>0)\))时记录一个操作 \(U\),碰到一个整点时记录两个操作 \(UR\)

比如我们现在要求 \(\sum_{x=1}^n \lfloor\frac{ax+b}c\rfloor\)​​​,我们就可以记录两个值 \(cnt,s\)​​​,当扫描到一个操作 \(U\)​​​ 时将 \(cnt+1\)​​​,扫描到 \(R\)​​​ 时将 \(s+cnt\)​​​,最后的 \(s\)​​ 就是答案。

做万欧的时候,每个问题都会被看成一个节点 \(f(a,b,c,n,U,R)\),表示我们想求关于 \(\lfloor\frac{ax+b}c\rfloor\) 的某个式子,其中的 \(x\)\((0,n]\) 的整值,碰到横线的操作序列是 \(U\),碰到竖线的操作序列是 \(R\)。我们发现 \(a\ge c\)\(a< c\) 的问题好像有一些不一样,所以我们将其分类讨论。

\(a\ge c\)​ 时,我们发现 \(\lfloor\frac{ax+b}c\rfloor=\lfloor\frac{(a\ \bmod\ c)x+b}c\rfloor+\lfloor\frac ac\rfloor x\)​,这说明每一个 \(R\)​ 操作之前至少会有连续的 \(\lfloor\frac ac\rfloor\)​ 个 \(U\)​(换句话说就是 \(x+1\)​,\(y\)​ 至少加 \(\lfloor\frac ac\rfloor\)​),于是我们可以将 \(R\)​ 变成 \(U^{\lfloor\frac ac\rfloor}R\)​,且把 \(a\)​ 变为 \(a\bmod c\)​。形式化的说,\(a\ge c\)​ 时,\(f(a,b,c,n,U,R)=f(a\bmod c,b,c,n,U,U^{\lfloor\frac ac\rfloor}R)\)​​。​这样我们就成功的把数据规模从 \(\max(a,c)\)​ 变成了 \(c\)​。注意这里的合并操作有结合律,但是没有交换律。

\(a < c\)​ 时我们发现我们没办法再用上面的方法减少数据规模了,但是我们可以借鉴 gcd 和 exgcd 的思路,考虑交换 \(a,c\)​。

具体而言,我们把我们的直线改写一下:\(y=\frac{ax+b}c\Leftrightarrow x=\frac{cy-b}a\),我们发现此时 \(a,c\) 交换了地位。这看起来很不错,好像可以直接把函数一变,把 \(U\)\(R\) 互换,把 \(n\)\(R\) 的个数变成 \(U\) 的个数来达到交换的目的,但是我们发现有一些细节问题:

  • 我们要求碰到整点时操作序列应该加上一个 \(UR\)​,但是 \(RU\) 交换之后加的顺序反了。
  • 我们的直线是从 \((0,\frac bc)\) 开始走的,我们利用了这个点 \(x=0\) 的性质,但是转化之后的起点并没有这个性质。
  • \(x=n\) 时,\(y\) 并不一定取得到整值。这会导致 \(n\) 不能直接变换。

我们考虑一条一条解决这些问题。

  • 我们摸到一个整点时是将其视为先摸到横线后摸到竖线的,但这里既然横竖交换了那我们就考虑先让其先摸到竖线后摸到横线:我们直接把新的直线往左平移 \(\frac 1a\),变成 \(x=\frac{cy-b-1}a\),这样可以解决这个问题,虽然这个方案听起来很傻逼。

  • 我们没办法让起始点的 \(y=0\),那么我们可以考虑找到直线经过的第一条横线,将其对应的 \(U\) 以及之前的所有 \(R\) 全部单独加上去,剩下的横竖翻转转成一个子问题。这样方程就变成了 \(x=\frac{c(y+1)-b-1}a=\frac{cy+c-b-1}a\),因为第一个 \(U\) 被删掉了,每个 \(U\) 的序号都 -1 了。

  • 我们没办法让结束点的 \(y\)​ 取整值,那我们就把最后一个 \(U\)​ 后面的所有 \(R\)​ 全部取下来单独算,然后同上。直线方程不变。

于是我们发现 \(f(a,b,c,n,U,R)=R^{cnt1}U+f(c,(c-b-1)\bmod a,a,cntU-1,R,U)+R^{cnt2}\)。推一下这几个常量式子发现:

  • \(cntU=\lfloor\frac{an+b}c\rfloor\)(其实就是把 \(x=n\) 带进去的 \(y\) 值向下取整),-1 是因为第一个 \(U\) 被干掉了;
  • \(cnt1=\lfloor\frac{c-b-1}a\rfloor\)​,把 \(y=0\)​​ 代入新的直线方程即可得到。注意要带新的方程,而且区间是开区间,不然若直线过的第一个 \(U\)​ 对应的是整点,会出现该 \(U\)​ 后面的那个 \(R\)​ 也被算进去的情况。
  • \(cnt2=n-\lfloor\frac{c\cdot cntU-b-1}a\rfloor\),把 \(y=m-1\) 代入新的直线方程即可得到。注意要带新的方程,而且区间是开区间,理由与上面类似。

后两条可以自己试着画画图理解一下,发现他们完美的避开了所有不该取的点而对该取的点没影响。


但是我知道这个之后怎么做题呢?

假设我还是想求 \(\sum_{x=1}^n \lfloor\frac{ax+b}c\rfloor\)​,我们定义一个结构体“状态”,一个状态里面记录三个数 \(cntx,cnty,s\)​,分别为 \(R\)​ 的个数,\(U\)​​ 的个数与我们已经求到的和。

我们考虑合并两个状态 \(S,T\)

  • \(ans.cntx = S.cntx+T.cntx\)
  • \(ans.cnty = S.cnty+T.cnty\)
  • \(ans.s = S.s+T.s+S.cnty*T.cntx\),最后一项的意义是把 \(T\) 拼在 \(S\) 后面相当于给 \(T\) 的每一项加上一个 \(S.cnty\),而 \(T\)\(T.cntx\) 项。

最后我们只需要考虑初始时候 \(U,R\)​ 的值。我们想要的是扫到 \(U\) 的时候 \(cnty+1\),扫到 \(R\) 的时候 \(cntx+1,s+cnty\)​。因此不难推出初始 \(U\)\(cnty=1\),初始 \(R\)\(cntx=1\),其他值 \(=0\)。​

于是我们做完了。类似的我们可以求出 \(\sum_{x=1}^n \lfloor\frac{ax+b}c\rfloor^2\)​​​​,\(\sum_{x=1}^n x\lfloor\frac{ax+b}c\rfloor\)​​​​,甚至可以往上面套一堆矩阵或者数据结构等。

万欧的时间复杂度是 \(O(T\log \max (a,c))\)\(T\) 是合并两个信息的时间:我们需要时间的地方只有每一层的 \(cnt1,cnt2\)\(\lfloor\frac ac\rfloor\)。容易发现 \(cnt1,cnt2\le \lfloor\frac ca\rfloor\),也就是上一层的 \(\lfloor\frac ac\rfloor\),所以每层所需的时间就是 \(O(T(\log a-\log c))\),而 \(c\) 又会在下一层变成分子,所以相邻两项的加减抵消,时间复杂度变成 \(O(T\log \max (a,c))\)。当然这只是比较理性的感性理解(

完结撒花ᕕ( ᐛ )ᕗ

posted @ 2022-02-23 17:03  恨妹不成穹  阅读(177)  评论(0编辑  收藏  举报