数论知识点全明星

数论知识点整合。(但是我数论很菜呀!!!)

质数

质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。

单个数质数判断方法

  1. 朴素算法:如果 n 不是质数,则 p,qN,pq=n ,不妨令 pn ,只要检验所有的小于 n 的数是否能整除 n 即可,时间复杂度为 O(n)
  2. Miller-Rabin算法:
    前置知识:二次探测定理——对于素数 p ,若 x21(modp) ,则 x±1(modp) ;费马小定理——对于素数 p ,满足 aN,apa(modp)
    假定我们的 n 是一个大于 2 的奇数(不然可以直接判断),如果它是质数,则 an11(modp) 。我们随意找一个 a(0,n) 进行检验,如果这个成立,则 n 可能是素数。
    与此同时,二次探测定理在一定程度上也能够检验素数,所以,将 n1 转化成 m×2t ,首先预处理出 x=am ,然后递归 ty=x2,x=y 如果 y=1 则检验 x 是否等于 1n1 ,如果不是,返回 false
    最后,如果 an11(modp) 成立,返回 true ,否则返回 false
    上述算法有 34 个概率正确,有 14 的概率错误。所以,检验 k 次的正确率就是 1(14)k ,当 k 取 5~7 时正确率就足够高了。

素数筛法

  1. 埃氏筛,暴力枚举每一个数的大于它的所有倍数,他们不然不是质数,复杂度为 O(nlnlnn)
  2. 欧拉筛/线性筛,顾名思义,这个做法是线性的,具体实现时,对于任何一个合数 n ,记它最小的质因子为 p ,数 n 只会被 np 筛掉。

因数倍数

gcd(a,b) 表示 ab 最大公因数; lcm(a,b)[a,b] 表示 ab 最小公倍数。

最大公因数求法

暴力枚举( O(min(a,b)) ),更相减损法,辗转相除法( O(logmax(a,b) )。

最小公倍数求法

[a,b]=a×b(a,b)

扩展欧几里得算法

求解关于 xy 的同余方程的整数特解 ax+by=gcd(a,b)
不妨令 a>b
a=ab×b+(amodb)
[ab×b+(amodb)]x+by=gcd(a,b)
b(ab×x+y)+(amodb)x=gcd(b,(amodb))
递归求解 bamodb ,直到 amodb=0 即可。

裴蜀定理

关于 xy 的同余方程 ax+by=c 有整数解的充要条件是 gcd(a,b)|c
必要性证明:
gcd(a,b)|ax,gcd(a,b)|by
gcd(a,b)|ax+by=c
充分性证明:根据拓展欧几里得定理 ax+by=gcd(a,b)

同余

a,pN 如果 p,qZ,a=q×p+r 则称 ar(modp)

除法逆元与欧拉定理

如果 ab1(modp) ,则称 ba 在模 p 意义下的乘法逆元,记为 a1 ,显然在 gcd(a,p)1 时不存在逆元。

费马小定理

对于质数 p ,满足 ap11(modp)

欧拉定理

对于 ap ,满足 aφ(p)1(modp) ,由于在 p 为质数时 φ(p)=p1 ,所以费马定理是欧拉定理的特殊形式。

拓展欧拉定理

对于任意的 a,p,bN,bφ(p)aba(bmodφ(p))+φ(p)(modp)

Wilson定理

对于质数 p ,有 (p1)!1(modp)

阶与原根

根据欧拉定理对于 ap ,满足 aφ(p)1(modp) ,因此满足 an1(modp) 的最小正整数 n 存在,这个 nap 的阶,记为 δp(a)

阶的相关性质

  1. a,a2aδp(a)p 两两不同余
  2. apaq(modn) ,则 pq(modδn(a))

原根

对于 ap ,若 δp(a)=φ(p) 则称 a 为模 p 的原根。
原根判定定理:对于 p3,apa 为模 p 的原根的充要条件是对于每一个 φ(p) 的质因数 q ,有 aφ(p)q1(modp)

同余方程(组)求解

CRT

求解同余方程组:
{xa1(modp1)xa2(modp2)xan(modpn) ,其中 p1,p2pn 两两互质。
我们知道,对于 L=i=1npii[1,n]N,kN,k×L0(modpi)
因为 pi×pi11(modn) ,所以 Lpi×(Lpi)1modpj={1,i=j0,otherwise ,其中 (Lpi)1 为模 pi 意义下的逆元 。
所以对于 X=i=1n(ai×Lpi×(Lpi)1modpi)modL 满足上述同余方程组。

exCRT

求解同余方程组:
{xa1(modp1)xa2(modp2)xan(modpn)
我们没有 p1,p2pn 两两互质的前提条件,也就意味着我们上述构造的先决条件没有了,因为它的结构十分一般,所以考虑两两合并。
考虑同余方程组 {xa1(modp1)xa2(modp2)
我们设 x=p1×q1+a1=p2×q2+a2
p1×q1p2×q2=a1a2 ,我们根据裴蜀定理知道,存在 q1,q2 的充分必要条件是 gcd(p1,p2)|a1a2
假设上述式子成立,我们根据 exgcd 可以得到一组 q1,q2 的特解,这两个同余方程组可以合并成 xp1×q1+a1(modlcm(p1,p2))
一直递归求解即可。

BSGS

求同余方程 axb(modp) ,其中 ap
根据欧拉定理,必然存在一个小于 φ(p) 的根,也就是有一个小于 p 的根。
N=p ,则 x 可以表示为 ANB ,其中 0A1,B<N
aANBb(modp)
aANbaB(modp)
预处理出所有的 aANbaB ,然后看是否有匹配的即可。

exBSGS

求同余方程 axb(modp)
没有和互质的条件,我们就尝试让 a,p 互质。
d1=gcd(a,p) ,如果 d1b ,同余方程必然无解 。
如果 d1b ,则 ad1×ax1bd1(modpd1)
这个时候如果满足互质关系,就可以直接BSGS了。否则,我们继续上述操作,找 d2=gcd(a,pd1)
直到 akd1d2dk×axkbd1d2dn(modpd1d2dn) ,其中 apd1d2dn
这也就意味着 akd1d2dkpd1d2dn ,乘上逆元移到右边就是正常的BSGS了。
当然,也有可能是有小于 k 的答案,我们只需要枚举它们即可。

高次同余方程

求解方程 xab(modp) ,其中 p 为质数,且 a(p1)
首先求出 p 的原根 g ,令 b=gvx=gu
gaugv(modp)
auv(modp1)
首先用BSGS求出 vu=v×a1 即可求出 x

组合数

定义 Cnm 与表示从 n 个元素中选 m 个的组合数,显然 Cnm=n!m!(nm)! ,一般也写作 (nm)

基本公式

  1. Cnm=Cnnm
  2. i=0nCni=2n,i=0n(1)iCni=0
  3. Cnmmod2=[n&m=m] <---(这个很重要)

Lucas定理

对于质数 p 有:(nm)(n/pm/p)×(nmodpmmodp)(modp)
其中 (nmodpmmodp) 可以直接预处理, (n/pm/p) 接着递归处理即可,求单个组合数的复杂度为 O(f(n)+g(n)logn) ,其中 f(n) 为预处理复杂度, g(n) 为单次求组合数复杂度。

exLucas定理

Lucas定理只能处理 p 为质数的情况,对于不是质数的,我们就需要用exLucas定理。
(nm)modP ,其中 P 可能是合数。
根据唯一分解定理 P=i=1npiαi ,其中 pi 为质数。
我们求出每一个 (nm)modpiαi ,然后用中国剩余定理即可。
也就是要求 n!m!(nm)!modpα ,需要求分母求逆元,但由于 m!(nm)! 不一定与质数 p 互质。所以考虑先提取出所有的 p
所求转化为 n!pxm!py(nm)!pz×pxyzmodpα
S(n)n! 除掉所有因数 p 的值。
现在考虑如何求 S(n)modpα
n!=(p×2p××npp)×(1×2×)
S(n)S(np)×(i=1,pipαi)npα×(nmodpα)!(modpα)
S(np) 递归做,后面的暴力做既可。

容斥

在计数时,必须注意没有重复,没有遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。

基本容斥

|i=1nAi|=T[1,n]N(1)|T|+1|iTAi|

minmax容斥

maxiS{ai}=TS(1)|T|+1miniT{ai}
miniS{ai}=TS(1)|T|+1maxiT{ai}

积性函数与迪利克雷卷积

积性函数

完全积性函数定义: a,bN,f(ab)=f(a)f(b)
常见完全积性函数:元函数 ϵ(n)=[n==1] ,恒函数 I(n)=1 ,单位函数 id(n)=n
积性函数定义: a,bN,ab,f(ab)=f(a)f(b)
常见积性函数:

欧拉函数 φ(n)

定义 φ(n) 表示不超过 n 的自然数中与 n 互质的数的个数。
如果 n 的唯一分解式为 n=i=1kpiαi ,则 φ(n)=ni=1kpi1pi
φ(ab)=φ(a)×φ(b)×gcd(a,b)φ[gcd(a,b)]
n=d|nφ(d) (欧拉反演)。

莫比乌斯函数 μ(n)

定义 μ(n)={1,n=1(1)k,n=i=1kpi0,otherwise ,其中 pi 为互异质数。
d|nμ(d)=[n==1]
d|nμ(d)d=φ(n)n

约数个数函数 d(n)

d(n)=d|n1

迪利克雷卷积

fg=d|nf(d)g(nd)
有定义可得 φI=id,μI=ϵ,μid=φ

莫比乌斯反演

fI=F ,即 F(n)=d|nf(d) ,则 Fμ=f ,即 f(n)=d|nμ(nd)F(d)
F(n)=n|df(d) ,则 f(n)=n|dμ(dn)F(d)

数论分块

基本思想

考虑数 nd
dn 时,nd 最多有 n 个取值。
d>sqrtn 时,ndnd<n 也最多只有 n 个取值。
所以我们需要求有关 nd 的求和时,只需要考虑这 2n 的值即可,复杂度为 O(n)

杜教筛

求积性函数 f(n) 的前 m 项的和 S(m)
我们先找到一个合适的积性函数 g(n)

i=1n(fg)(i)
=i=1nd|if(d)g(id)
=d=1ng(d)i=1ndf(i)
=d=1ng(d)S(nd)
所以 g(1)S(n)=i=1n(fg)(i)d=2ng(d)S(nd)
所以我们找到合适的 g(n) 使得 (fg)(n) 的前缀和方便求解,然后数论分块递归求后面一部分即可。
单纯递归的复杂度为 O(n34)
考虑线性筛预处理出前 m 个的答案,则复杂度为 O(m+nm) ,当 m=n23 时,取最优复杂度 O(n23)

Min25筛

这是一种亚线性筛法,能够在 O(n34logn) ,算出 i=1nf(i) 的值。
而比较好实现的方法被证明是 O(n1ϵ) 的。
加下来我们记 P=p1,p2,p3 为小于等于 n 的质数集, P 为小于等于 n 的质数集, LPF 为最小质因数(lowest prime factor)。
当然,使用这种筛法需要满足一些限制:

  1. f(n) 需要是一个积性函数。
  2. f(p),pP 是一个关于 p 的低维多项式,即 f(p)=i=0naipi,pP
  3. f(pk),pP 能够快速求值。

很多时候,给定的 f(p) 会和质数有关,所以考虑将所有的质数提取出来。
i=1nf(i)=iPf(i)+i=1n[iP]f(i)
首先考虑如何处理出所有的质数。
因为我们知道 f(p),pP 是一个关于 p 的低维多项式,所以我们可以把它的每一位单独拆开,而且每一位都是一个完全积性函数 f(i)=ik
然后Min_25发现了一种DP方式来处理这个问题(接下来的处理过程中可以不考虑 1 ,时具体实现而定)。
g(n,i)=j=1n[jPorLPFj>pi]jk
那么我们需要的就是 g(n,|P|)
考虑从 g(n,i1) 转移到 g(n,i) ,发现我们是减少了一些数,因为我们的限制从 LPFj>pi1 提升到了 LPFj>pi
我们减少了所有 LPFj=pi 的,因为它是完全积性函数,所以可以将删掉的这些数全部从 f(x) 替换成 f(pi)f(xpi)
在除了一个 pi 之后,它的LPF仍然会大于 pi
所以 g(n,i)=g(n,i1)f(pi)(g(npi,i1)g(pi1,i1)) ,根据定义,我们知道 g(pi1,i1)=j=1i1pjk
g(n,i)=g(n,i1)f(pi)(g(npi,i1)j=1i1pjk)
因为任何小于 n 的合数一定有一个小于 n 的质因数,所以我们只需要用线性筛预处理出小于等于 n 的质数即可。
其次,因为 nab=nab ,所以g中的前一维必然是 nx 的形式,所以只会有 O(n) 种取值。
现在我们再来考虑另一个DP式。
S(n,i)=j=1n[LPFj>pi]f(j) ,答案就是 S(n,0)
仍然对贡献进行分类:

  1. >pi 的质数,在第 k 维上的总贡献为 ak(g(n,|P|)jPpik)
  2. 其他,由于 f(n) 是积性函数,所以考虑将所有 LPF=pjpj 项指数为 e 的全部提取出来,贡献为 f(pje)(S(npje,j)+[e1])

所以 S(n,i)=res+pjen&j>if(pje)(S(npje,j)+[e1]) ,其中 res 为质数部分的贡献。
有人证明,求 S 是不记忆化复杂度是正确的,所以直接递归即可,边界情况就是 pin
一定要注意自己的算法到底有没有算1 ,上述算法是没有算的,所以最终答案为 S(n,0)+1

多项式科技

拉格朗日插值

对于一个最高次项次数小于等于 n 的多项式 f(x) ,确定了 n+1 个不同的值,即 f(xi)=yi,ij,xixj,i,j=1,2n+1 时,我们可以唯一确定多项式 f(x)
此时 f(x)=i=1n+1yij=1,jin(xxj)j=1,jin(xixj)
因为我们知道 j=1,jin(xxj)j=1,jin(xixj)={0,xxi1,x=xi
这样我们就可以快速的求出一个多项式的值了。

FFT

我们知道在确定了 n+1 个值的时候,可以唯一确定一个 n 次多项式,对于一般多项式,我们知道若 h(x)=f(x)g(x)h(xi)=f(xi)g(xi)
所以对于两个多项式的乘法,我们可以用 O(n) 的时间对它的 n 个值进行乘除运算即可。
这时候我们需要找到合适的值,所以就用到了复数。
ωn=ei2πn=cos(2πn)+isin(2πn)
我们知道 ωn2=ωn2ω2nk+ω2nn+k=0
n=2m
f(ωnk)=i=0nai×(ωnk)i
f(ωnk)=i=0n2a2i×(ωnk)2i+i=0n2a2i+1×(ωnk)2i+1
f(ωnk)=i=0n2a2i×(ωn2k)i+ωnk×i=0n2a2i+1×(ωn2k)i
这样我们就可以递归求出 f(ωn0),f(ωn1)f(ωnn1) 了。
不难发现,它的逆变换是类似的,只是将单位根 ωn 取成 ei2πn ,最后再乘一个 1n 即可。
这里 n 需要等于 2m

NTT

因为FFT无法解决对答案取模的情况,所以我们考虑将单位根 ωn 替换成原根。
最常见 Mod=998244353=717223+1 ,其中 g=3
由于 gqn=1(modMod) ,只需要将 ωn 替换成 gq
显然 φ(998244353)=998244352=717223 。所以对于不同的 n 进行替换即可。

FMT

或卷积运算

由于题目的需要,我们有时得把卷积运算进行一定的变换。
本来的正常运算是处理 ck=i+j=kaibj 的,这个时候FFT和NTT才适用。
考虑卷积运算 ck=i|j=kaibj
FMT(A)i=jiAj
所以 FMT(A)i×FMT(B)i=jiAj×kiBk
=jikiAjBk
=lij|k=lAjBk=FMT(C)i
不难发现这是高维前缀和。

与卷积运算

考虑卷积运算 ck=i&j=kaibj
FMT(A)i=ijAj
所以 FMT(A)i×FMT(B)i=ijAj×ikBk
=ijikAjBk
=ilj&k=lAjBk=FMT(C)i
快速求解就是高维后缀和。

FWT

异或卷积运算

考虑卷积运算 ck=ij=kaibj 。这时候我们需要一个新的变换。
这是,沃尔什想出来了一个特别的变换。
FWT(A)i=j=0n(1)popcnt(i&j)Ajpopcnt(x) 表示 x 的二进制表示下 1 的个数。
那么 FWT(A)i×FWT(B)i=(j=0n(1)popcnt(i&j)Aj)×(j=0n(1)popcnt(i&j)Bj)
=j=0nk=0n(1)popcnt(i&j)+popcnt(i&k)AjBk
我们知道, popcnt(i&j)+popcnt(i&k)popcnt(i&(jk))
所以 FWT(A)i×FWT(B)i=j=0nk=0n(1)popcnt(i&(jk))AjBk=FWT(C)i
考虑用分治优化变换过程。
因为变换的过程和 i 的二进制下每一位有关,所以考虑每一位的影响。
考虑它其中的某一位。当且仅当 ij 均为 1 的时候,在变换中会对答案乘上 1 的贡献,所以 FWT(A)i=FWT(A0)+FWT(A1),FWT(A)i+n2=FWT(A0)iFWT(A1)i
逆运算需要带一个 1n 的系数。

子集卷积

考虑卷积运算 Ck=i|j=k,i&j=0AiBj
发现需要满足的第一个条件 i|j=k 就是或卷积运算。
而第二个条件,就需要满足 popcnt(i)+popcnt(j)=popcnt(k)
所以我们考虑加一维按 popcnt(i) 分开即可。
然后就是子集卷积,复杂度比FMT多了一维 popcnt

posted @   Xun_Xiaoyao  阅读(235)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
/* 鼠标点击求赞文字特效 */
点击右上角即可分享
微信分享提示