整数环以及丢番图方程

收录于 · 算法竞赛

定义 带余除法

对于给定的任意整数 a,b 其中 b>0 ,存在唯一的整数对 q,r 使得 a=bq+rr[0,b1]

证明用到良序原则 (自然数的非空子集必然存在一个最小元素)。

先考虑存在性的证明。构造集合 S={abk|kZ,abk0} ,那么必然存在一个最小元 r ,满足 aqb=r,a=qb+r 。接下来证明 r<b ,这很显然,因为如果 rb 则存在 r=rb0 ,也在集合 S 中,矛盾。接下来证明唯一性。由于 r0 ,所以只存在唯一的 r 满足 0r<b ,那么也就只有唯一 q

定义 整除

a=bq 则称 b 整除 a ,记作 ba 。称 ba 的约数。整除具有传递性。

定义 最大公约数

对于两个数,如果 dadb 则称其为公约数,其中最大的称为最大公约数记作 gcd(a,b)

定义 素数 只有 1 和其本身两个约数的数是素数,除了 1 和其本身还有其他的约数的数是合数, 10 既不是素数也不是合数。

定理 唯一分解定理

任意正整数 n=i=1mpici ,其中 pi 是质数。

定理 欧几里德算法

gcd(a,b)=gcd(b,amodb) 。其中 amodb 代表 a 带余除法 b 所得的余数 r

证明之前先证一个引理, gcd(a,b)=gcd(b,ab) 。假设 gcd(a,b)=d ,设 a=ud,b=vd,gcd(u,v)=1 ,那么 ab=d(uv) 。所以 gcd(b,ab)=dgcd(v,uv)=d 。这里用反证法,如果 gcd(v,uv)=k>1 ,那么设 v=kx,(uv)=kyu=k(x+y) ,那么 gcd(u,v) 至少是 k 。这和 gcd(u,v)=1 矛盾。

有了这个引理之后,根据带余除法的定义,就可以证明该定理了。

定理 扩展欧几里德算法

定理 裴蜀定理 方程 ax+by=gcd(a,b) 存在整数解 x=s,y=t

纯数学证明可以构造集合并继续应用良序定理,这里给出扩展欧几里德算法的直接构造。

gcd(a,b)=d欧几里得算法 的最后一步会得到两个数 d,0 ,然后令,就得到了一组解。假设当前我们要求一组解满足 ax+by=d ,且我们已经得到了一组解满足 bs+(amodb)t=d 。拆开来得到 at+b(sabt)=d ,所以我们可以令 而得到一组解。一直这么推下去就可以得到最后的答案,其实这是一个高斯消元的过程。

定义 同余

如果整数 a,bm 满足 m(ab) ,则称 a,bm 同余。记作 ab(modm)

命题 如果 a1b1(modm) 而且 a2b2(modm) ,则 a1±a2b1±b2(modm)a1a2b1b2(modm)

定理 消去律

a,b,cZm 是一个正整数。如果 gcd(c,m)=1 ,且 acbc(modm) ,则 ab(modm)

m(acbc)=c(ab) ,由于 gcd(c,m)=1 所以 mab

定义 乘法逆元

a1 满足 aa11(modm) 。显然乘法逆元不一定存在。

求关于 x同余方程 ax1(modb) 的最小正整数解。

也就是 ax+by=1 的最小正整数解,运用扩展欧几里德算法即可。

1,2\hdots,np 的逆元。

p=ki+j,0j<i

ki+j0(modp)<br>(ki+j)i1j10(modp)<br>kj1+i10(modp)<br>i1kj1(modp)<br>i1(p[p/i])×(pmodi)1(modp)

定义 等价类

显然, 同余关系 是一种等价关系。如果有一种等价关系定义在集合 S 上,则该等价关系会把集合 S 划分为不相交的子
集,这些子集我们称为等价类。

定义 同余类

考虑整数集合 Z ,设 m 为正整数,则模 m 的同余关系把 Z 划分为 m 个等价类。任意整数 a 所落在的等价类记为 [a]m ,即所有模 m 同余的整数形成的集合。

m 同余类 的集合记为 Z/mZ ,该集合恰好有 m 个元素,即: Z/mZ=[0]m,[1]m,,[m1]m

定义 最小剩余系

Z/mZ 的所有最小非负代表元的集合 {0,1,2,,m1}

定理 费马小定理

ap11(modp)

引理 a×imodp,1a<i1,2,,p1 的一个置换。

反证法,若存在 aiaj(modp) ,则 ij(modp) 矛盾。

下证费马小定理

i=1p1ii=1p1ai=ap1(i=1)p1i(modp)

所以显然有 ap11(modp)

定义 欧拉函数

1,2,,n 中与 n 互质的数的个数为 φ(n) ,即为欧拉函数。

命题p 是素数, φ(p)=p1,φ(pc)=pc1(p1)

显然 p 的剩余系里都与 p 互质,那么每 p 个数里会有 p1 个互质,于是 φ(pc)=pcp1p

定理 欧拉函数是积性函数,即 gcd(a,b)=1φ(ab)=φ(a)φ(b)

这其实可以用剩余系得思想来推,即证明 Z/aZ×Z/bZ 双射 Z/abZ 。当然还可以用容斥的角度,类似上面的证明。还有一个比较巧妙的用了狄利克雷卷积,这里就不过论述。

命题 d|nφ(d)=n

{1,2,,n}=dn{x[1,n]Zgcd(x,n)=d} ,而后者刚好就是 φ(nd)

欧拉函数的应用

定理 欧拉定理

aφ(m)1(modm),gcd(a,m)=1

定义 简化剩余系

所有和 m 互质的数构成的剩余类的集合。

证明欧拉定理等价于证明简化剩余系 ×a 是简化剩余系的置换,其实和上面的反证法一模一样。

定理 扩展欧拉定理

好复杂,但是可以根据欧拉定理记忆,先丢一个证明

定理 素数的整除性

a,bZp 为素数。如果 pab ,则 papb

推论, n>0,nab,gcd(n,a)=1nb

定理 欧几里得定理

素数有无穷多。

使用反证法。设素数有穷, p1,p2,pn ,构造 N=1+i=1npi ,这个数显然不能被任意一个素数整除,那么也就不能被任意一个数整除,所以它也是一个素数。

定理 狄利克雷定理

存在无穷多的素数满足 pa(modm) ,其中 gcd(a,m)=1

定理 素数定理

π(x) 为素数个数,则 limxπ(x)x/lnx=1

定理 威尔逊定理

p 是素数的充要条件是 (p1)!1(modp)

p=1 时显然不行。

先证充分性,对于 有 a1b1 ,我们只需将 与 a1 配对即可,充分性得证。

必要性显然,若 p 为合数则取一个质因子即可。

定理 Lucas 定理

p 是质数。

(nm)modp=(n/pm/p)×(nmodpmmodp)modp

定理 库默尔定理

p(nm) 中的位数等于 n+mp 进制下进位的次数。

定理 扩展 Lucas 定理

等价于求

(nm)modpc

考虑由于逆元不一定存在所有不能直接求逆元,把 p 的倍数全部除掉,得到 n!=p[n/p]([n/p])! ,后面的东西显然可以预处理。前面的部分递归做即可。

code

定义 素性测试

素性测试问题,即如何判断一个大的奇整数 n 是否素数。

试除法

枚举 2n1 ,看看能不能整除 n 。这是最暴力的方法,时间复杂度

对上述算法优化,约数是成对出现的所以枚举到 n 即可,时间复杂度 O(n)

Miller-Rabin 素性测试

费马小定理的逆定理虽然不成立,但是可以勉强用来判断。而满足费马小定理的合数称作卡麦尔数。

定理 二次探测定理

如果 p 为质数,则 x21modpx[1,p1] 的解为 x=1,p1

我们可以在费马小定理后以此判断 a(p1)/2,a(p1)/4 是不是 1/1

已经证明若随机选择 k 个底数则这样做出现伪素数 的概率不大于 14k

code

定义 原根

对于群 Zn循环群 ,则称其生成元是 n 的原根。即满足阶是 φ(n) 的元素 g

满足 n=2,4,pa,2pa 的群 Zn 都是循环群。

原根可以生成群内所有元素,原根有 φ(φ(n)) 个。

定理 原根判定定理

g 是原根,当且仅当 i,gφ(n)pi/1(modφ(n)),φ(n)=pici

最小原根的数量级是 n0.25 的。

定理 中国剩余定理

物不知数问题:

有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?
化解为线性方程组来表示即为:

{x2(mod3)x3(mod5)x2(mod7)

对于这个方程组我们可以对于每个方程构造一个数使得其模其它模数为 0,模自己的模数为答案。

即对于上面的方程可以构造:

{a1=35a2=63a3=30

全部加起来即可得到一组特解 x0=128 。然后得到通解 x=x0+Mt,tZM 是模数的最小公倍数。

可以得到最小正整数解: x=23

通过这个例子我们可以得到下面的结论:

如果模数两两互素,设 M=Πi=1nmi,Mi=Mmi 。根据古人的智慧我们可以构造出一个特解: x0=i=1nbiMiMi1

容易证明这个特解是对的,然后我们就可以得到通解: x=x0+M

多数情况下模数不是质数,所以要用 exgcd 求逆元。

定理 扩展中国剩余定理

这个时候,我们就要每个方程轮流按顺序求解。

假设我们已经求出一个解。这个解满足前个方程。现在我们将其和第个方程合并。

具体操作就是将其代入第个方程来解出得到未知数的一个通解。

设第个方程是形如的。

解方程的过程:

x0+Mta(modb)Mtax0(modb)

如果这个方程无解则整个方程组无解。

g=gcd(M,b)

解得: t=t0+bgt,tZ

带回 x 的解,得: x=x0+M(t0+bgt)=x0+Mt0+lcm(M,b)t,tZ

x0 更新为 x0+Mt0M 更新为 lcm(M,b) 即可。

第一个方程显然可以得到一组解

定义 二次剩余

p 是奇素数, a 是与 p 互质的整数,询问是否存在 x 使得 x2a(modp)

定义 勒让德符号

定义 amodp 的勒让德符号为:

(ap)={1(exist)1(not)0(pa)

定义 欧拉准则

(ap)ap12(modp)

(ap)=1 时, x,x2a,(x2)(p1)/21ap121

否则, a(p1)/21/0 ,又 0ap11=(a(p1)/21)(a(p1)/2+1)a(p1)/2+10

推论

p 是奇素数,则

(1p)={1(pmod4=1)1(pmod4=1)

定理 二次互反律

(pq)(qp)=(1)(p1)(q1)4

定理 Cipolla 算法

我们随机一个 n ,令 ω=n2a 。将数系扩充成 Fω ,相当于复数里面的 i 。我们反复随机 n ,直到 n2a 不是一个二次剩余。然后大概可以证明这样的 n 的大概有一半,所以期望随机二次既可以随机出一个,然后答案就是 (n+ω)p+12

证明先考虑两个引理:

ωp=ω<br>ap+bp(a+b)p(modp)

第一个考虑拆成 (ω2)p12×ω ,第二个考虑二项式定理 展开。

然后这个证明就很显然了,直接暴力平方展开 然后替换,最后是一个平方差 的形式,相信大家都会。

显然 x,x 都是二次剩余。

提交记录

定义 离散对数

是一个整数 x 对于给定的 a,b,m 满足下面的方程:

axb(modm)

记作 x=logab 。通常情况先我们把这叫做 【阶】, index 。记作 indab

显然离散对数不一定存在。比如: 2x3(mod7)

定理 BSGS

(a,m)=1 时我们可以使用大步小步(Baby Step Giant Step)算法。

注意到 (a,m)=1 ,我们有欧拉定理 aφ(m)1 。所以 ak 至多有 φ(m) 种取值(也就是其循环节为 φ(m) )。设 x=kBr,0rB1B 是我们随便取的一个数,那么有 akBbar ,我们预处理 a0,a1aB1 ,枚举 k 即可求出 x (其实这个过程已经可以求出 了)。

时间复杂度 O(B+φ(m)B) ,随便根号平衡一下得 O(φ(m))

定理 扩展 BSGS

用于解决 (a,m)1 时的情况。设 d=gcd(a,m) ,那么有 adax1bd(modmd) 。于是这么一路递归除下去即可。注意判断无解,当 d 不整除 b 时即无解。

递归完之后就可以正常的 bsgs 了。

定理 pohlig-hellman 算法

这里我们不妨设模数是个大质数 P 。我们可以找出一个原根 g ,然后求 gxh(modP)

算法思想大概就是想把 p1 质因数分解为 piei ,然后计算 xxi(modpiei)

考虑 gp11(modP) 。所以有

(gx)p1piei=(gxi+kpiei)p1piei(gp1piei)xihp1piei(modP)

所以令 gp1piei,hp1piei 取代原来的 g,h 就可以在 piei 范围内求 xi 了。

所以我们需要解决的问题变成了 gxh(modP) ,其中 x[0,piei1] 。考虑将 x 写成 pi 进制数,显然有 ei 位,从低到高逐位确定。即 x=x0+x1pi+x2pi2+\hdots+xe1piei1 。然后当我们想要求 xj 的时候,就计算 (gx)p1pij+1 ,容易发现这又可以写成 gxjh(modP) 的形式,但是这时 xj 的范围就变成了 [0,pi1] 。这个时候我们就可以直接 BSGS 了。

综上所述,整个算法的复杂度为 O(ei(logP+pi)) 。比普通 BSGS 有了不小的提升。

定理 pollard-rho 算法

定义 线性递推数列

主要研究二阶常系数齐次线性递推,即斐波那契数列 。下面的公式仅考虑一般情况( n2

fn=fn1+fn2fn1fn+1fn2=(1)nfn+k=fkfn+1+fk1fnfafbabgcd(fa,fb)=fgcd(a,b)

定理 皮萨诺周期

斐波那契数列模 m 的周期不超过 6m

WC 2021 斐波那契

这种分析的方法太经典了。

f0=0,f1=,fn=fn2+fn1fn 就是常见的斐波那契数列,易得 Fn=afn1+bfn

于是我们只需找出最小的 n 使得 afn1=bfn(modm) ,如果 m 是质数我们可以直接预处理(这里用到结论 f 的循环节是 O(m) 的)。

否则考虑除掉 gcd(a,b,m) ,变成 a1fn1=b1fn(modm1) ,注意到这时还是有可能不互质。

但是相邻斐波那契数是互质的,记 p=gcd(a1,m1)=gcd(fn,m1),q=gcd(b1,m1)=gcd(fn1,m1) ,可以再除掉这个 p,q 。于是有 a2fn1=b2fn(modm2) ,这时直接预处理 fnfn1modm2 即可。

用一个三元组维护 (p,q,fnfn1) 维护即可。

本文使用 Zhihu On VSCode 创作并发布