无极之地
WUJI
无极之地。记录所思所见,慢慢写下去。
阶与原根
世界时钟 北京 --:--:-- 东京 --:--:-- UTC --:--:-- 伦敦 --:--:-- 纽约 --:--:-- 二次同余看起来只是 x 2 ≡ a ( m o d p ) x^2 \equiv a \pmod p x 2 ≡ a ( mod p ) ,真正要先回答的却是:这个平方在模 p p p 下存不存在。根可以以后再找(Cipolla 或 Tonelli–Shanks),判别本身已经够用一套完整的语言:二次剩余、勒让德符号、欧拉准则,再加二次互反律把计算压到手算能做完的规模。
二次剩余在说什么
设 p p p 是奇素数,a a a 是整数。方程
x 2 ≡ a ( m o d p ) x^2 \equiv a \pmod p x 2 ≡ a ( mod p ) 要么无解,要么恰有两个互相反数的解(p ∣ a p \mid a p ∣ a 时只有零解 x ≡ 0 x \equiv 0 x ≡ 0 )。
当 p ∤ a p \nmid a p ∤ a 且方程有解时,称 a a a 是模 p p p 的二次剩余 ;无解则称二次非剩余 。p ∣ a p \mid a p ∣ a 时,a a a 与 p p p 不互素,通常不把它算进「剩余 / 非剩余」这两类,只说方程有平凡解 。
解若存在,必成对出现。若 x 0 2 ≡ a x_0^2 \equiv a x 0 2 ≡ a ,则 ( − x 0 ) 2 ≡ a (-x_0)^2 \equiv a ( − x 0 ) 2 ≡ ,且 为奇素数时 。反过来,同一个剩余不会对应超过这两个根:若 ,则 ,只能是 。所以「有解」和「恰有两解」在 时是同一件事。
模 7 7 7 看一遍就清楚。1 2 , 2 2 , 3 2 1^2,2^2,3^2 1 2 , 2 2 , 3 2 分别同余 1 , 4 , 2 1,4,2 1 , 4 , 2 ,再往后 、 、 ,只是重复。所以模 的二次剩余是 ,非剩余是 。一半一半,不是巧合:乘法群 是循环群,平方映射的核是 ,像的大小恰好是 。
同余可以像等式那样乘,但「两边开方」没有一般法则。x 2 ≡ 2 ( m o d 7 ) x^2 \equiv 2 \pmod 7 x 2 ≡ 2 ( mod 7 ) 有解,x 2 ≡ 3 ( m o d 7 ) x^2 \equiv 3 \pmod 7 x 2 ≡ 3 没有,不能从「 比 大」读出任何信息。一次同余里 的存在性由 一锤定音;二次同余没有这么短的算术条件,必须另造判别式。
勒让德符号 把「剩不剩余」收成一个取值只有 0 , ± 1 0,\pm 1 0 , ± 1 的记号,就是勒让德符号。对奇素数 p p p 和整数 a a a ,
( a p ) = { 0 若 p ∣ a 1 若 p ∤ a 且 a 是二次剩余 − 1 若 p ∤ a 且 a 是二次非剩余 \left(\frac{a}{p}\right)
=
\begin{cases}
0 & \text{若 } p \mid a \\
1 & \text{若 } p \nmid a\text{ 且 }a\text{ 是二次剩余} \\
-1 & \text{若 } p \nmid a\text{ 且 }a\text{ 是二次非剩余}
\end{cases} ( p a ) = 于是 x 2 ≡ a ( m o d p ) x^2 \equiv a \pmod p x 2 ≡ a ( mod p ) 有解,当且仅当 ( a p ) ≠ − 1 \bigl(\frac{a}{p}\bigr) \neq -1 ( p a 。符号为 时有且仅有零解;为 时恰有两解。若只要「能不能开方」,看符号是否为 即可;若还要根的个数,把 和 分开。
同余类相同则符号相同:( a p ) = ( a m o d p p ) \bigl(\frac{a}{p}\bigr)=\bigl(\frac{a \bmod p}{p}\bigr) ( p a ) = ( p a 。手算第一步永远是把底数收进 ,再分解质因数。不要对一个比 还大的合数直接互反。
( a b p ) = ( a p ) ( b p ) \left(\frac{ab}{p}\right)
=
\left(\frac{a}{p}\right)
\left(\frac{b}{p}\right) ( p ab ) = ( p a ) 所以 ( a 2 p ) = 1 \bigl(\frac{a^2}{p}\bigr)=1 ( p a 2 ) = 1 (只要 p ∤ a p \nmid a p ∤ a ),( 。负数先拆出 :
( − 1 p ) = ( − 1 ) ( p − 1 ) / 2 = { 1 p ≡ 1 ( m o d 4 ) − 1 p ≡ 3 ( m o d 4 ) \left(\frac{-1}{p}\right)
= (-1)^{(p-1)/2}
=
\begin{cases}
1 & p \equiv 1 \pmod 4 \\
-1 & p \equiv 3 \pmod 4
\end{cases} ( p − 1 ) = ( 2 p ) = ( − 1 ) ( p 2 − 1 ) / 8 = { 1 p ≡ ± 1 ( m o d 8 ) − 1 p ≡ ± 3 ( m o d 8 ) \left(\frac{2}{p}\right)
= (-1)^{(p^2-1)/8}
=
\begin{cases}
1 & p \equiv \pm 1 \pmod 8 \\
-1 & p \equiv \pm 3 \pmod 8
\end{cases} ( p 2 ) = 这两条加上积性,已经能消掉符号里的 − 1 -1 − 1 和 2 2 2 。剩下的奇数底数,交给互反律。记忆时可以分开:模 4 4 4 管 − 1 -1 − 1 ,模 8 8 8 管 2 2 2 ,互反管两个奇素数谁换谁。三条各管一块,不要混用。
欧拉判别法 勒让德符号的定义依赖「有没有平方根」,直接用定义等于枚举,模一大就没意义。欧拉准则把它变成一次幂运算:
( a p ) ≡ a ( p − 1 ) / 2 ( m o d p ) \left(\frac{a}{p}\right)
\equiv
a^{(p-1)/2} \pmod p ( p a ) ≡ a ( p − 1 ) /2 ( mod 右边在模 p p p 下只可能是 0 0 0 、1 1 1 或 p − 1 p-1 p − 1 。最后一种就是 − 1 -1 − 1 。于是:
p ∣ a p \mid a p ∣ a 时两边都是 0 0 0 ;
否则费马小定理给出 a p − 1 ≡ 1 a^{p-1}\equiv 1 a p − 1 ≡ 1 ,所以 a ( p − 1 ) / 2 ≡ ± 1 a^{(p-1)/2}\equiv \pm 1 a ,正负恰好对应剩余与非剩余。
为什么对得上?设 g g g 是模 p p p 的一个原根,a ≡ g k a \equiv g^k a ≡ g k 。a a a 是平方当且仅当 k k k 为偶数,而
a ( p − 1 ) / 2 ≡ g k ( p − 1 ) / 2 ≡ ( g ( p − 1 ) / 2 ) k ≡ ( − 1 ) k ( m o d p ) a^{(p-1)/2} \equiv g^{k(p-1)/2} \equiv (g^{(p-1)/2})^k \equiv (-1)^k \pmod p a ( p − 1 ) /2 ≡ g k ( p − 1 ) /2 k k k 偶则 1 1 1 ,k k k 奇则 − 1 -1 − 1 。这就是欧拉准则。不必真的找出原根:存在性由有限域理论保证,计算时只做模幂。
手算时指数可以先模 p − 1 p-1 p − 1 (费马),再快速幂。p p p 很小时,列出 1 2 , … , ( p − 1 2 ) 2 1^2,\dots,\bigl(\frac{p-1}{2}\bigr)^2 1 2 , … , ( 2 往往更快,因为后一半平方只是重复。欧拉准则的价值在模数变大之后:枚举要 次乘法,模幂只要 次。
它给出判别,不给出根。a ( p − 1 ) / 2 ≡ 1 a^{(p-1)/2}\equiv 1 a ( p − 1 ) /2 ≡ 1 只告诉你平方根存在,并不构造出 x x x 。想把 x x x 找出来,需要 Tonelli–Shanks 或 Cipolla,那是另一篇文章的事。
二次互反律 欧拉准则的指数是 ( p − 1 ) / 2 (p-1)/2 ( p − 1 ) /2 ,模 p = 10 9 + 7 p=10^9+7 p = 1 0 9 + 7 这类数时计算机毫无压力,纸上算 a 5 ⋅ 10 8 a^{5\cdot 10^8} a 就不现实。二次互反律把 和 绑在一起,让两个素数可以交换位置。
( p q ) ( q p ) = ( − 1 ) p − 1 2 ⋅ q − 1 2 \left(\frac{p}{q}\right)
\left(\frac{q}{p}\right)
= (-1)^{\frac{p-1}{2}\cdot\frac{q-1}{2}} ( q p ) ( p q ) 右边只取决于 p , q p,q p , q 模 4 4 4 的类:
若 p , q p,q p , q 中至少有一个 ≡ 1 ( m o d 4 ) \equiv 1 \pmod 4 ≡ 1 ( mod 4 ) ,则 ( p q ) = ( q p ) \bigl(\frac{p}{q}\bigr)=\bigl(\frac{q}{p}\bigr) ( q ;
完整证明(高斯引理、格点计数,或圆上的高斯和)篇幅不短,这里略去。高斯引理把 ( a p ) \bigl(\frac{a}{p}\bigr) ( p a ) 写成一串最小绝对剩余的符号乘积,再数格子就能看到互反两边差一个 ( − 1 ) (-1) ( − 1 ) 的指数;高斯和则把同样的符号嵌进单位根的平方和。知道名字即可,手算用的是结论。
用法比证明更常被问起:把较大的素数降到较小的模上,再拆因子、消 2 2 2 、必要时再互反,直到底数变成 1 1 1 。每次互反都要先看两个素数模 4 4 4 是否都是 3 3 3 ,漏掉改号是最常见的笔误。
高斯和的补充形式也常用。对奇数 n > 0 n>0 n > 0 ,
( n p ) = ( p n ) ( − 1 ) n − 1 2 ⋅ p − 1 2 \left(\frac{n}{p}\right)
= \left(\frac{p}{n}\right)
(-1)^{\frac{n-1}{2}\cdot\frac{p-1}{2}} ( p n ) = ( n p 右边的 ( p n ) \bigl(\frac{p}{n}\bigr) ( n p ) 已不是勒让德而是雅可比符号,但当 n n n 本身是素数时两者重合。手算时只要记住:先把底数收进 [ 0 , p ) [0,p) [ 0 , p ) ,再分解。
取模,使 0 ≤ a < p 0 \le a < p 0 ≤ a < p 。若 a = 0 a=0 a = 0 ,符号为 0 0 0 ,停。
写出 a a a 的素因子分解,积性拆成若干 ( q p ) \bigl(\frac{q}{p}\bigr) ( ,负数先拆 。
这和下面递推代码是同一条路,只是人按质因数拆,机器按除以 2 2 2 和取模走。
手算例子
例一:欧拉准则直接判 问 3 3 3 是不是模 7 7 7 的二次剩余。( 7 − 1 ) / 2 = 3 (7-1)/2=3 ( 7 − 1 ) /2 = 3 ,
3 3 = 27 ≡ 6 ≡ − 1 ( m o d 7 ) 3^3 = 27 \equiv 6 \equiv -1 \pmod 7 3 3 = 27 ≡ 6 ≡ − 1 ( mod 7 ) 故 ( 3 7 ) = − 1 \bigl(\frac{3}{7}\bigr)=-1 ( 7 3 ) = − 1 ,无解。对照前面的枚举:1 , 2 , 4 1,2,4 1 , 2 , 4 里没有 3 3 3 。
再看 2 2 2 模 7 7 7 :2 3 = 8 ≡ 1 2^3=8\equiv 1 2 3 = 8 ≡ 1 ,所以 ( 2 7 ) = 1 \bigl(\frac{2}{7}\bigr)=1 ( 7 。的确 。用 的闭式验一次: ,符号应为 ,一致。
例二:互反律降模 计算 ( 5 17 ) \bigl(\frac{5}{17}\bigr) ( 17 5 ) 。5 5 5 和 17 17 17 都是 ≡ 1 ( m o d 4 ) \equiv 1 \pmod 4 ≡ 1 ,互反不改号:
( 5 17 ) = ( 17 5 ) = ( 2 5 ) \left(\frac{5}{17}\right)
= \left(\frac{17}{5}\right)
= \left(\frac{2}{5}\right) ( 17 5 ) = ( 5 17 ) = 5 ≡ − 3 ( m o d 8 ) 5\equiv -3 \pmod 8 5 ≡ − 3 ( mod 8 ) ,故 ( 2 5 ) = − 1 \bigl(\frac{2}{5}\bigr)=-1 ( 5 2 ) = 。于是 无解。
若不用互反,欧拉准则要算 5 8 m o d 17 5^8 \bmod 17 5 8 mod 17 。也能做:5 2 = 25 ≡ 8 5^2=25\equiv 8 5 2 = 25 ≡ 8 ,5 4 ≡ 64 ≡ 13 5^4\equiv 64\equiv 13 , ,同一答案,只是步数更多。
例三:先拆因子再互反 计算 ( 15 17 ) \bigl(\frac{15}{17}\bigr) ( 17 15 ) 。15 = 3 ⋅ 5 15=3\cdot 5 15 = 3 ⋅ 5 ,
( 15 17 ) = ( 3 17 ) ( 5 17 ) \left(\frac{15}{17}\right)
= \left(\frac{3}{17}\right)
\left(\frac{5}{17}\right) ( 17 15 ) = ( 17 3 ) ( 例二已经得到后者为 − 1 -1 − 1 。前者:3 ≡ 3 ( m o d 4 ) 3\equiv 3\pmod 4 3 ≡ 3 ( mod 4 ) ,17 ≡ 1 ( m o d 4 ) 17\equiv 1\pmod 4 17 ≡ 1 ( mod 4 ) ,互反不改号,
( 3 17 ) = ( 17 3 ) = ( 2 3 ) \left(\frac{3}{17}\right)
= \left(\frac{17}{3}\right)
= \left(\frac{2}{3}\right) ( 17 3 ) = ( 3 17 ) = 3 ≡ 3 ( m o d 8 ) 3\equiv 3\pmod 8 3 ≡ 3 ( mod 8 ) ,故 ( 2 3 ) = − 1 \bigl(\frac{2}{3}\bigr)=-1 ( 3 2 ) = 。两个因子都是 ,乘积为 。所以 是模 的二次剩余。
谁是根?从小到大试:1 2 , … , 7 2 1^2,\dots,7^2 1 2 , … , 7 2 同余 1 , 4 , 9 , 16 , 8 , 2 , 15 1,4,9,16,8,2,15 1 , 4 , 9 , 16 , 8 , 2 , 15 。果然 7 2 = 49 ,另一个根是 。判别只保证存在,根仍要另找——模很小就枚举,模很大才需要 Tonelli–Shanks。
例四:带负号 ( − 3 13 ) \bigl(\frac{-3}{13}\bigr) ( 13 − 3 ) 。先拆 − 1 -1 − 1 :13 ≡ 1 ( m o d 4 ) 13\equiv 1\pmod 4 13 ≡ 1 ,故 。再算 。两者都 ? , ,仍不改号:
( 3 13 ) = ( 13 3 ) = ( 1 3 ) = 1 \left(\frac{3}{13}\right)
= \left(\frac{13}{3}\right)
= \left(\frac{1}{3}\right)
= 1 ( 13 3 ) = ( 3 13 ) = 所以 ( − 3 13 ) = 1 \bigl(\frac{-3}{13}\bigr)=1 ( 13 − 3 ) = 1 。验算:4 2 = 16 ≡ 3 4^2=16\equiv 3 4 2 = 16 ≡ ,则 对应……不对, 说明 是剩余, ,应看 。 ,确实有解。负数务必先处理符号,不要把 直接拿去和 互反——互反律要求两个正奇素数。
例五:两个素数都是 3 m o d 4 3 \bmod 4 3 mod 4 计算 ( 7 19 ) \bigl(\frac{7}{19}\bigr) ( 19 7 ) 。7 7 7 和 19 19 19 都 ≡ 3 ( m o d 4 ) \equiv 3 \pmod 4 ≡ 3 ,互反要改号:
( 7 19 ) = − ( 19 7 ) = − ( 5 7 ) \left(\frac{7}{19}\right)
= -\left(\frac{19}{7}\right)
= -\left(\frac{5}{7}\right) ( 19 7 ) = − ( 7 19 ) 5 ≡ 1 ( m o d 4 ) 5\equiv 1\pmod 4 5 ≡ 1 ( mod 4 ) ,7 ≡ 3 ( m o d 4 ) 7\equiv 3\pmod 4 7 ≡ 3 ( mod 4 ) ,这一步不改号:
( 5 7 ) = ( 7 5 ) = ( 2 5 ) = − 1 \left(\frac{5}{7}\right)
= \left(\frac{7}{5}\right)
= \left(\frac{2}{5}\right)
= -1 ( 7 5 ) = ( 5 7 ) = 于是 ( 7 19 ) = − ( − 1 ) = 1 \bigl(\frac{7}{19}\bigr)=-(-1)=1 ( 19 7 ) = − ( − 1 ) = 1 。8 2 = 64 ≡ 7 ( m o d 19 ) 8^2=64\equiv 7 \pmod{19} 8 ,另一个根是 。若第一下忘了改号,会得到 ,和验算对不上。
欧拉准则交叉验证:( 19 − 1 ) / 2 = 9 (19-1)/2=9 ( 19 − 1 ) /2 = 9 ,7 2 = 49 ≡ 11 7^2=49\equiv 11 7 2 = 49 ≡ 11 ,7 4 ≡ 121 ≡ 7 7^4\equiv 121\equiv 7 7 , ,故 ,同为 。
例六:较大底数先取模 问 100 100 100 是不是模 31 31 31 的二次剩余。先取模:100 ≡ 7 ( m o d 31 ) 100\equiv 7 \pmod{31} 100 ≡ 7 ( mod 31 ) ,故 ( 100 31 ) = ( 7 31 ) \bigl(\frac{100}{31}\bigr)=\bigl(\frac{7}{31}\bigr) ( 。两者都 ,改号:
( 7 31 ) = − ( 31 7 ) = − ( 3 7 ) \left(\frac{7}{31}\right)
= -\left(\frac{31}{7}\right)
= -\left(\frac{3}{7}\right) ( 31 7 ) = − ( 7 31 ) 3 3 3 与 7 7 7 也都 ≡ 3 ( m o d 4 ) \equiv 3 \pmod 4 ≡ 3 ( mod 4 ) ,再改一次号:
− ( 3 7 ) = − ( − ( 7 3 ) ) = ( 1 3 ) = 1 -\left(\frac{3}{7}\right)
= -\Bigl(-\left(\frac{7}{3}\right)\Bigr)
= \left(\frac{1}{3}\right)
= 1 − ( 7 3 ) = − ( − ( 3 所以有解。100 = 10 2 100=10^2 100 = 1 0 2 ,当然是剩余——这个例子用来提醒:底数本身是平方时,只要 p ∤ a p \nmid a p ∤ a ,符号必为 1 1 1 ,取模后的 7 7 7 看起来「不像平方」,互反仍会回到 1 1 1 。写程序时不必先判断「是不是完全平方」,准则自己会处理。
一份可直接用的实现 欧拉准则最短,适合确认单个符号。快速幂是 O ( log p ) O(\log p) O ( log p ) 次乘法。模数保证是素数时,它比递推更不容易写错:没有互反改号,也没有抽因子 2 2 2 。代价是指数大,手算不合适,机器无所谓。
def legendre_euler ( a : int , p : int ) -> int :
""" 欧拉准则求勒让德符号 (a/p)。p 必须是奇素数。 """
if p <= 2 or p % 2 == 0 :
raise ValueError ( " p 必须是奇素数 " )
a %= p
if a == 0 :
return 0
r = pow ( a , ( p - 1 ) // 2 , p )
return - 1 if r == p - 1 else r pow 的三参数形式就是模幂。返回值已经是 0 , ± 1 0,\pm 1 0 , ± 1 ,不要把 p − 1 p-1 p − 1 留在外面。
互反律可以写成递推,避免大指数,也更接近手算顺序:不断把底数模掉、抽出因子 2 2 2 、交换两个奇数。下面同时给出雅可比符号——当模数是奇素数时它就是勒让德。
def jacobi ( a : int , n : int ) -> int :
""" 雅可比符号 (a/n)。n 为正奇数。n 为奇素数时即勒让德符号。 """
if n <= 0 or n % 2 == 0 :
raise ValueError ( " n 必须是正奇数 " )
a %= n
result = 1
while a :
while a % 2 == 0 :
a //= 2
if n % 8 in ( 3 , 5 ):
result = - result
递推版每一步把问题缩小,复杂度仍是 O ( log 2 n ) O(\log^2 n) O ( log 2 n ) 量级的位运算,和欧几里得同一数量级。竞赛里模数已经保证是素数时,两份代码应当给出相同答案;不一致就回头检查「p − 1 p-1 p − 1 有没有当成 − 1 -1 − 1 」或「交换时有没有漏掉两个 3 m o d 4 3 \bmod 4 3 mod 」。
递推过程可以对照例五。求 ( 7 19 ) \bigl(\frac{7}{19}\bigr) ( 19 7 ) :两者都是奇数,先交换并因 7 ≡ 19 ≡ 3 ( m o d 4 ) 7\equiv 19\equiv 3\pmod 4 7 ≡ 19 ≡ 3 ( mod 4 改号,变成 ;再交换(不改号)得 ;抽出 , 再改一次号,得到 。和手算同一条路,只是循环代替了纸上的箭头。
jacobi 对合数模也有定义,但 ( a n ) = 1 \bigl(\frac{a}{n}\bigr)=1 ( n a ) = 1 不 蕴含 x 2 ≡ a ( m o d n ) x^2\equiv a\pmod n x 2 ≡ 有解。雅可比是勒让德按素因子的乘积:若 ,则
( a n ) = ∏ i ( a p i ) k i \left(\frac{a}{n}\right)
= \prod_i \left(\frac{a}{p_i}\right)^{k_i} ( n a ) = i ∏ ( 即使乘积为 1 1 1 ,也可能每个因子都是 − 1 -1 − 1 而个数为偶,整体「看起来像剩余」,局部却无解。例如 ( 2 15 ) = ( 2 3 ) ( 2 5 ) = ( − 1 ) ( − 1 ) = 1 \bigl(\frac{2}{15}\bigr)=\bigl(\frac{2}{3}\bigr)\bigl(\frac{2}{5}\bigr)=(-1)(-1)=1 ( 15 2 ) ,而 与 都无解,更不必说模 。要判合数模,应拆成素因子幂再对每个素因子用勒让德(必要时再用亨泽尔提升),不能只看雅可比。
Solovay–Strassen 素性测试正是利用这一点:随机抽 a a a ,比较 a ( n − 1 ) / 2 a^{(n-1)/2} a ( n − 1 ) /2 与雅可比符号。合数上两者容易不一致,素数上欧拉准则强制相等。写符号函数时若模数可能是合数,返回值的含义要在注释里写清。
写代码时容易踩的坑 先取模再算。a a a 为负时,Python 的 % 会收成 [ 0 , p ) [0,p) [ 0 , p ) ,欧拉准则和递推都能接着用。若语言里负余数保持负号,必须自己先规范化,否则 ( − 3 13 ) \bigl(\frac{-3}{13}\bigr) ( 13 − 3 ) 会走错分支。
欧拉准则的输出在 { 0 , 1 , p − 1 } \{0,1,p-1\} { 0 , 1 , p − 1 } 里,不是 { 0 , ± 1 } \{0,\pm 1\} { 0 , ± 1 } 。漏掉 p-1 → -1 这一步,后面当乘法因子用就会把符号乘飞。
互反律的前提是两个不相等的奇素数 。底数是 1 1 1 、2 2 2 或偶数时不要互反,先用闭式或拆 2 2 2 。p = q p=q p = q 时符号是 0 0 0 ,不是去套公式。
( 2 p ) \bigl(\frac{2}{p}\bigr) ( p 2 ) 看的是模 8 8 8 ,不是模 4 4 4 。p ≡ 3 ( m o d 4 ) p\equiv 3\pmod 4 p ≡ 只决定 ,不决定 。 且 , 而 。
积性是乘性的,不是加性的。( a + b p ) \bigl(\frac{a+b}{p}\bigr) ( p a + b ) 与 ( a p ) + ( b p ) \bigl(\frac{a}{p}\bigr)+\bigl(\frac{b}{p}\bigr) ( p 没有关系。例三里 ,但 ,不能拆成两个符号相加。
勒让德等于 1 1 1 只说明存在平方根,代码若接着「随便开方」会得到浮点误差。整数解要枚举、或走 Tonelli–Shanks / Cipolla。模 2 2 2 是退化情形:x 2 ≡ a ( m o d 2 ) x^2\equiv a\pmod 2 x 2 ≡ a ( mod 2 ) 对 a ≡ 0 , 1 a\equiv 0,1 a ≡ 都有解,多数实现直接特判。
合数模上「剩不剩余」不能只用一个符号。中国剩余定理把问题拆开:对每个 p k p^k p k 有解,整体才有解。p k p^k p k 上从模 p p p 的解往上抬,是亨泽尔引理,条件是导数 2 x 2x 2 x 在该素因子处可逆,也就是奇素数上的非零根都能抬。p = 2 p=2 p = 的高次幂要单独处理, 已有额外限制, 才可能继续往 抬。
和开平方算法的边界 判别解决「有没有」,开平方解决「是谁」。素数模上的标准算法是 Tonelli–Shanks:先把 p − 1 p-1 p − 1 写成 2 s ⋅ q 2^s\cdot q 2 s ⋅ q (q q q 奇),再在 2 2 2 -西罗子群里调整。Cipolla 则在 F p 2 \mathbb{F}_{p^2} 里取一个模 的非剩余构造二次扩张。两者都以勒让德符号为前置:没有剩余就直接停,有剩余才进入开方。
一次同余提供求逆和中国剩余定理,二次剩余提供存在性。合在一起,才能把 x 2 ≡ a ( m o d m ) x^2\equiv a\pmod m x 2 ≡ a ( mod m ) 在一般模上拆开、抬上去。更高次剩余要原根和指标,那是离散对数一侧的语言。
所以不必把勒让德符号看成竞赛里的冷门公式。它是二次同余的开关:先用欧拉或互反把 ± 1 \pm 1 ± 1 算对,再决定要不要去找根。手算走互反,代码走模幂,两套答案应当咬合。把存在性、符号计算和开平方三件事分开,这一层就不会和一次同余搅在一起。
0
a
x 0 ≢ − x 0 x_0 \not\equiv -x_0 x 0 ≡ − x 0 p ∣ ( x − y ) ( x + y ) p \mid (x-y)(x+y) p ∣ ( x − y ) ( x + y ) 4 2 ≡ 2 4^2 \equiv 2 4 2 ≡ 2
( Z / p Z ) × (\mathbb{Z}/p\mathbb{Z})^\times ( Z / p Z ) × (
mod
7
)
gcd ( a , m ) \gcd(a,m) g cd( a , m ) ⎩
⎨
⎧
0 1 − 1 若 p ∣ a 若 p ∤ a 且 a 是二次剩余 若 p ∤ a 且 a 是二次非剩余
)
=
− 1
mod
p
)
{ 0 , 1 , … , p − 1 } \{0,1,\dots,p-1\} { 0 , 1 , … , p − 1 } (
p b
)
1 p ) = 1 \bigl(\frac{1}{p}\bigr)=1 ( p 1 ) = 1
( − 1 ) ( p − 1 ) /2 =
{ 1 − 1 p ≡ 1 ( mod 4 ) p ≡ 3 ( mod 4 )
( − 1 ) ( p 2 − 1 ) /8 =
{ 1 − 1 p ≡ ± 1 ( mod 8 ) p ≡ ± 3 ( mod 8 )
p
)
( p − 1 ) /2
≡
± 1
≡
( g ( p − 1 ) /2 ) k ≡
( − 1 ) k
( mod p )
p − 1
) 2
5
⋅
1
0 8
( p q ) \bigl(\frac{p}{q}\bigr) ( q p ) ( q p ) \bigl(\frac{q}{p}\bigr) ( p q )
=
( − 1 ) 2 p − 1 ⋅ 2 q − 1
p
)
=
( p q )
若两者都 ≡ 3 ( m o d 4 ) \equiv 3 \pmod 4 ≡ 3 ( mod 4 ) ,则 ( p q ) = − ( q p ) \bigl(\frac{p}{q}\bigr)=-\bigl(\frac{q}{p}\bigr) ( q p ) = 。 )
(
−
1
) 2 n − 1 ⋅ 2 p − 1
p q
)
( − 1 p ) \bigl(\frac{-1}{p}\bigr) ( p − 1 ) 每个 q = 2 q=2 q = 2 用模 8 8 8 的闭式;每个奇素数 q q q 用互反律换成 ( p m o d q q ) \bigl(\frac{p \bmod q}{q}\bigr) ( q p ,并按模 决定是否改号。 新的底数更小,回到第 2 2 2 步,直到出现 ( 1 q ) = 1 \bigl(\frac{1}{q}\bigr)=1 ( q 1 ) = 1 或 ( 0 q ) = 0 \bigl(\frac{0}{q}\bigr)=0 ( 。
2
)
=
1
3 2 = 9 ≡ 2 3^2=9\equiv 2 3 2 = 9 ≡ 2 7 ≡ − 1 ( m o d 8 ) 7\equiv -1 \pmod 8 7 ≡ − 1 ( mod 8 )
( mod 4 )
( 5 2 )
−
1
x 2 ≡ 5 ( m o d 17 ) x^2\equiv 5 \pmod{17} x 2 ≡ 5 ( mod 17 ) 5 4
≡
64 ≡
13
5 8 ≡ 169 ≡ 16 ≡ − 1 5^8\equiv 169\equiv 16\equiv -1 5 8 ≡ 169 ≡ 16 ≡ − 1 17 5
)
( 3 2 )
−
1
≡ 15 7^2=49\equiv 15 7 2 = 49 ≡ 15
(
mod
4
)
( − 1 13 ) = 1 \bigl(\frac{-1}{13}\bigr)=1 ( 13 − 1 ) = 1 ( 3 13 ) \bigl(\frac{3}{13}\bigr) ( 13 3 ) ≡ 1 ( m o d 4 ) \equiv 1\pmod 4 ≡ 1 ( mod 4 ) 3 ≡ 3 ( m o d 4 ) 3\equiv 3\pmod 4 3 ≡ 3 ( mod 4 ) 13 ≡ 1 ( m o d 4 ) 13\equiv 1\pmod 4 13 ≡ 1 ( mod 4 ) ( 3 1 ) =
1
3
6 2 = 36 ≡ 10 6^2=36\equiv 10 6 2 = 36 ≡ 10
( mod 4 )
=
− ( 7 5 )
( 5 2 ) =
− 1
2
=
64 ≡
7
( mod 19 )
4
≡
121 ≡
7
7 8 ≡ 49 ≡ 11 7^8\equiv 49\equiv 11 7 8 ≡ 49 ≡ 11 7 9 ≡ 11 ⋅ 7 = 77 ≡ 1 ( m o d 19 ) 7^9\equiv 11\cdot 7=77\equiv 1 \pmod{19} 7 9 ≡ 11 ⋅ 7 = 77 ≡ 1 ( mod 19 )
31
100
)
=
( 31 7 )
≡ 3 ( m o d 4 ) \equiv 3 \pmod 4 ≡ 3 ( mod 4 ) =
− ( 7 3 )
7
)
)
=
( 3 1 ) =
1
a
,
n
=
n
,
a
if a % 4 == 3 and n % 4 == 3 :
result = - result
a %= n
return result if n == 1 else 0
def legendre ( a : int , p : int ) -> int :
""" 勒让德符号 (a/p)。调用方保证 p 为奇素数。 """
return jacobi ( a , p )
if __name__ == " __main__ " :
print ( legendre_euler ( 3 , 7 )) # -1
print ( legendre_euler ( 2 , 7 )) # 1
print ( legendre ( 5 , 17 )) # -1
print ( legendre ( 15 , 17 )) # 1
print ( legendre ( - 3 , 13 )) # 1
print ( legendre ( 0 , 13 )) # 0
print ( legendre ( 7 , 19 )) # 1
print ( legendre ( 100 , 31 )) # 1
4
)
− ( 19 7 ) = − ( 5 7 ) -\bigl(\frac{19}{7}\bigr)=-\bigl(\frac{5}{7}\bigr) − ( 7 19 ) = − ( 7 5 ) − ( 7 5 ) = − ( 2 5 ) -\bigl(\frac{7}{5}\bigr)=-\bigl(\frac{2}{5}\bigr) − ( 5 7 ) = − ( 5 2 ) 5 ≡ 5 ( m o d 8 ) 5\equiv 5\pmod 8 5 ≡ 5 ( mod 8 )
a
( mod n )
n = p 1 k 1 ⋯ p r k r n=p_1^{k_1}\cdots p_r^{k_r} n = p 1 k 1 ⋯ p r k p i
a
)
k i
=
( 3 2 ) ( 5 2 ) =
( − 1 ) ( − 1 ) =
1
x 2 ≡ 2 ( m o d 3 ) x^2\equiv 2\pmod 3 x 2 ≡ 2 ( mod 3 ) x 2 ≡ 2 ( m o d 5 ) x^2\equiv 2\pmod 5 x 2 ≡ 2 ( mod 5 ) 3
( mod 4 )
7 ≡ 3 ( m o d 4 ) 7\equiv 3\pmod 4 7 ≡ 3 ( mod 4 ) 7 ≡ − 1 ( m o d 8 ) 7\equiv -1\pmod 8 7 ≡ − 1 ( mod 8 ) ( − 1 7 ) = − 1 \bigl(\frac{-1}{7}\bigr)=-1 ( 7 − 1 ) = − 1 ( 2 7 ) = 1 \bigl(\frac{2}{7}\bigr)=1 ( 7 2 ) = 1
a
)
+
( p b )
( 15 17 ) = 1 \bigl(\frac{15}{17}\bigr)=1 ( 17 15 ) = 1
0
,
1
2
x 2 ≡ a ( m o d 8 ) x^2\equiv a\pmod 8 x 2 ≡ a ( mod 8 ) a ≡ 1 ( m o d 8 ) a\equiv 1\pmod 8 a ≡ 1 ( mod 8 ) 16 , 32 , … 16,32,\dots 16 , 32 , … F
p 2
− ( p q )
mod
q
)
q
0
)
=
0
r
二次剩余与勒让德符号 · 无极之地