数论入门笔记
公式较多,渲染可能较慢,正常现象(
这个憨批将近一年没摸数论知识了,于是重新学习了一遍。为了防止学习第三遍,所以打算写个东西记录一下这次我复习到的(很小一部分)数论知识。
因为我的数论知识非常垃圾,所以出错是很正常的,直接跟我对线即可,我会改的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\)。
莫反的两大形式:
证明:
(形式一)
考虑 \(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]\)。因此有
证毕。
(形式二)
证毕。
杜教筛
是一种亚线性筛法,可以做到积性函数求前缀和,但是使用难度不低。
先扔一些前置的东西:
狄利克雷卷积
定义两数论函数的狄利克雷卷积 \((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]\)。
这些积性函数又有一些性质:
- 对于任意 \(f\),\(f*\epsilon=f\)。
- \(\mu * I=\epsilon\)。
- \(\phi*I=id\)。
- \(\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)\),所以有
4:将 3 等式两边卷上一个 \(\mu\),则有
杜教筛
搞了那么多,跟杜教筛有啥关系呢(
假设我们想求一个积性函数 \(f\) 的前缀和 \(S(n)=\sum_{i=1}^nf(i)\)。
我们不妨找另一个积性函数 \(g\),使得 \(f*g\) 是一个很优美的积性函数。我们可以得出:
因为我们想求 \(S(n)\),所以我们可以带 \(S(n)\) 的一项提出来。
剩下的 \(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。
性质
- \(a^{\frac{p-1}2}\equiv1\pmod p\) 或 \(a^{\frac{p-1}2}\equiv-1\pmod p\)
由费马小定理,显然。注意我们排除了 0 的情况。
- \(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\)。
这玩意又被叫做欧拉判别准则,还有个勒让德符号可以方便的表示这个式子:
- 在 \([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^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))\)。当然这只是比较理性的感性理解(
完结撒花ᕕ( ᐛ )ᕗ