引入问题 :
给定一个奇素数 (p),求 (p) 最小的原根 (g)。
对于一个质数,它的原根 (g) 需要满足什么条件?
对于 (k in [1, p - 1]),(g^k) 完美遍历了 ([1, p - 1]) 的所有数。((g^k) 两两不相等)
如何快速判断一个数 (x) 是否是原根?
根据费马小定理可得 (x^{p - 1} equiv 1 pmod p),即任意数 (x) 至少有一个长度为 (p - 1) 的循环节。
如果还会出现小于 (p - 1) 的循环节,这个循环节的大小一定会整除 (p - 1)。(循环节倍长还是循环节)
令 (a_i) 为 (p - 1) 的质数因子。
如果出现了了小于 (p - 1) 的循环节,一定会有一个长度为 (frac {p - 1} {a_i}) 的循环节,即 (x^{frac {p - 1} {a_i}} equiv 1 pmod p)。
先 (O(sqrt n)) 预处理出 (p - 1) 的质数因子,这样就可以在 (O(log^2 n)) 的时间复杂度内判断一个数是不是原根了。
怎么求最小的原根?
暴力枚举!
由于原根的密度很大,最小原根的大小大约是 (n^{0.25}) 级别的,所以暴力枚举再判断就行。
推广 : 对于一个合数求原根,只需要把上面的 (p - 1) 换成 (varphi (n)) 即可。
应用
(x^c equiv m pmod p)
给定 (p), (m), (c),求 (x)。
利用 (g^k equiv x),有 ((g^c)^k equiv m pmod p)。
由于 (g^c) 是一个确定的值,那么问题就转化成求 (k) 了,直接 bsgs 即可。
但好像上面这个问题有 polylog 的做法
(x^c equiv m pmod p),若 (c imes k equiv 1 pmod{varphi (p)}),则 (x equiv m^k pmod p)。