[数论] 原根
书接上回...
我们知道,我们在使用 FFT 时,靠的是单位根 \(\omega\)。
数学家证明这是复数域中唯一符合条件的数。
可是它的浮点误差和带来的巨大运算时间使我们有点不能接受。
于是,我们想想能不能找个替代品替代掉 \(\omega\)。
于是,原根就出现了!
原根的引入
阶
对于一个数 \(x\) ,在 \(\bmod p\) 的意义下,存在一个最小的正整数 \(k\),使得 \(a^k\equiv1\),特别的,当 \(k\) 不存在时,我们认为 \(k=\infty\)。
这么个理解法,举个例子:
在 \(\bmod 7\) 情况下,\(3\) 的阶是 \(6\)。因为 \(3,2,6,4,5,1\)。
说白了就是求循环节。
所以有 \(\infty\) 的情况就是 \(a\) 的 \(p\) 的因数,到 \(0\) 后死循环了。
根据伟大的欧拉函数,我们知道这个循环节最多是 \(\varphi (p)\)。
我们记 \(\delta_p(a)\) 表示 \(a\) 的阶,在 \(\mod p\) 意义下。
原根
我们记 \(\delta_p(a)=\varphi(p)\) 的 \(a\),叫做 \(a\) 的原根。
只有 \(2,4,2p^c,p^c\) 的数才存在原根。(\(p\in prime\),\(p\ne 2,c\in \mathbb{N^+}\))
证明最后写。
性质
-
对于 \(a^n\equiv 1,\delta_p(a)|n\)
-
如果我们知道一个原根 \(g\) ,可以构造出其它所有原根。
我们把 \((p,i)=1\) 的 \(i\) 求出来。然后找到任意一个原根 \(g\),然后 \(g\) 像 \(g^2\) 连边,\(g^2\) 向 \(g^3\) 连边..... 这样,最终会变成一个简单环。
每个原根等同于往这个环上每次跳 \(x\) 跳边,然后遍历每个点一次回到原点。
所以,原根的数量是 \(\varphi(\varphi(n))\)。 -
原根是稠密的,最小原根近似于 \(n^{0.25}\)。
求法
我们知道性质后,我们想直接枚举出一个原根。
我们想想怎么判断一个数 \(x\) 是不是原根。
- 引理:只需判断 \(\varphi(p)\) 的因数即可
假设我们已经得到一个环,存在一个正确的原根 \(g\) 每次跳一步得到。假设每次跳 \(x\) 步,环大小为 \(n\),那么最终这个环的大小是 \(\dfrac{lcm(x,n)}{x}=\dfrac{n}{\gcd(x,n)}\)
所以我们可以证明得到,环的大小总是 \(n\) 的约数,所以我们枚举每个约数看看跳这么多步是不是 \(1\) 即可。
求一个原根的算法就已经得到了,时间复杂度是 \(O(p^{0.25}w(p)\log p)\)。
然后就是一个原根推所有原根。构造一下就行了,时间复杂度是 \(O(\varphi(p)\log p)\)。
其实呢,求原根是很纸币的行为,有一个就够了,要那么多干啥。
可以查这个:原根表

浙公网安备 33010602011771号