BSGS
问题:给定整数 a , b , p a,b,p a,b,p,其中 a , p a,p a,p 互质,求方程 a x ≡ b (   m o d    p ) a^x\equiv b(\,\mathrm {mod}\; p) ax≡b(modp) 的解。
由于 a , p a,p a,p 互质,所以我们可以在模 p p p 意义下执行关于 a a a 的乘除运算。
我们将 x x x 表示为 i × t − j i\times t-j i×t−j( t = ⌈ p ⌉ t=\lceil\sqrt p\rceil t=⌈p⌉, i ∈ [    0 , t    ] i\in[\;0,t\;] i∈[0,t], j ∈ [    0 , t − 1    ] j\in[\;0,t-1\;] j∈[0,t−1]),原方程就变成 a i × t − j ≡ b (   m o d    p ) a^{i\times t-j}\equiv b(\,\mathrm{mod}\;p) ai×t−j≡b(modp),也即 ( a t ) i ≡ b × a j (   m o d    p ) (a^t)^i\equiv b\times a^j(\,\mathrm{mod}\;p) (at)i≡b×aj(modp)。
这样表示的话,显然 x ∈ [    0 , p − 1    ] x\in[\;0,p-1\;] x∈[0,p−1],至于为什么,在下文中有解释,先接着看吧。
然后我们枚举 j ∈ [    0 , t − 1    ] j\in[\;0,t-1\;] j∈[0,t−1],将得到的 b × a j    m o d    p b\times a^j\;\mathrm{mod}\;p b×ajmodp 插入一个哈希表中(也可以用 unordered_map 维护)。
然后我们枚举 i ∈ [    0 , t    ] i\in[\;0,t\;] i∈[0,t],计算出 ( a t ) i    m o d    p (a^t)^i\;\mathrm{mod}\;p (at)imodp,在哈希表中查找是否有对应的 j j j,如果有,那么这时的 i × t − j i\times t-j i×t−j 就是答案,直接返回就行,否则就继续枚举。
时间复杂度为 O ( n ) O(\sqrt n) O(n)。
现在我们来解决一下上文留下的问题。
先来证明一个公式: a k    m o d    ( p − 1 ) ≡ a k (   m o d    p ) a^{k\;\mathrm{mod}\;(p-1)}\equiv a^k(\,\mathrm{mod}\; p) akmod(p−1)≡ak(modp)。
k    m o d    ( p − 1 ) k\;\mathrm{mod}\;(p-1) kmod(p−1) 也就是 k − m ( p − 1 ) k-m(p-1) k−m(p−1),原式可以变成 a k − m ( p − 1 ) ≡ a k (   m o d    p ) a^{k-m(p-1)} ≡ a^k (\,\mathrm{mod}\; p) ak−m(p−1)≡ak(modp)。
继续化简,变成 a k a m ( p − 1 ) ≡ a k (   m o d    p ) \frac{a^k} { a^{m(p-1)} }≡ a^k (\,\mathrm{mod}\; p) am(p−1)ak≡ak(modp)。
也就是说,如果 a m ( p − 1 ) ≡ 1 (   m o d    p ) a^{m(p-1)} ≡ 1 (\,\mathrm{mod}\; p) am(p−1)≡1(modp),那么式子就成立。
由费马小定理知,当 p p p 为质数且 gcd ( a , p ) = 1 \gcd(a,p) = 1 gcd(a,p)=1 时, a p − 1 ≡ 1 (   m o d    p ) a^{p-1} ≡ 1 (\,\mathrm{mod}\; p) ap−1≡1(modp)。
也即, a m ( p − 1 ) ≡ 1 (   m o d    p ) a^{m(p-1)}\equiv 1(\,\mathrm{mod}\;p) am(p−1)≡1(modp),故原式得证。
所以说,如果原方程有解的话,那在 [    0 , p − 1    ] [\;0,p-1\;] [0,p−1] 中必然有一个解,所以枚举到 p p p 就可以了。
exBSGS
很多时候, a , p a,p a,p 是不互质的,这时 B S G S \mathrm{BSGS} BSGS 就不再适用,我们就需要把这个算法扩展一下。
设 d = gcd ( a , p ) d=\gcd(a,p) d=gcd(a,p),显然 d > 1 d>1 d>1,令 a = a ′ × d a=a'\times d a=a′×d, p = p ′ × d p=p'\times d p=p′×d,则:
( a ′ × d ) x ≡ b (   m o d    p ′ × d ) (a'\times d)^x\equiv b(\,\mathrm{mod} \;p'\times d) (a′×d)x≡b(modp′×d)
不难发现,如果 b b b 不是 d d d 的倍数,那么只有当 b = 1 b=1 b=1 时才有解(此时 x = 0 x=0 x=0),否则就无解。因此可以把 b = 1 b=1 b=1 的情况特判一下,其他情况下只有 b b b 是 d d d 的倍数时才有解,那就令 b = b ′ × d b=b'\times d b=b′×d,则:
( a ′ × d ) x ≡ b ′ × d (   m o d    p ′ × d ) (a'\times d)^x\equiv b'\times d(\,\mathrm{mod} \;p'\times d) (a′×d)x≡b′×d(modp′×d)
消去一个 d d d,则:
a ′ × ( a ′ × d ) x − 1 ≡ b ′ (   m o d    p ′ ) a'\times (a'\times d)^{x-1}\equiv b'(\,\mathrm{mod} \;p') a′×(a′×d)x−1≡b′(modp′)
把 a ′ a' a′ 又换成 a d \frac{a}{d} da,得到
a d × a x − 1 ≡ b ′ (   m o d    p ′ ) \frac{a}{d}\times a^{x-1}\equiv b'(\,\mathrm{mod} \;p') da×ax−1≡b′(modp′)
由于这样处理之后,只能保证 a ′ a' a′ 和 p ′ p' p′ 是互质的,并不能说 a a a(即 a ′ × d a'\times d a′×d) 和 p ′ p' p′ 是互质的,所以要继续这样处理,直到 gcd ( a , p ) = 1 \gcd(a,p)=1 gcd(a,p)=1。假如我们做了 n u m num num 次处理,且每次的 d d d 之积为 D \mathrm D D,则:
a n u m D × a x − n u m ≡ b D (   m o d    p D ) \frac{a^{num}}{\mathrm D}\times a^{x-num}\equiv \frac{b}{\mathrm D}(\,\mathrm{mod} \;\frac{p}{\mathrm D}) Danum×ax−num≡Db(modDp)
此时的 gcd ( a , p D ) = 1 \gcd(a,\frac{p}{\mathrm D})=1 gcd(a,Dp)=1,就可以用 B S G S \mathrm {BSGS} BSGS 了。
注意我们这样解出来是 x ≥ n u m x≥num x≥num 的解,还要特判一下 [    0 , n u m − 1    ] [\;0,num-1\;] [0,num−1] 中是否有合法解。
而且我们解出来的实际上是 x − n u m x-num x−num 的值,因此最后还要加上一个 n u m num num。
模板题:[SPOJ 3105] Mod