二次剩余 (Quadratic Residue)
二次剩余 (Quadratic Residue)
只考虑奇质数 \(P\) 的情况
设求 \(x^2\equiv a\pmod P\) 的一个 \(x\)。
判断
由费马小定理 \(x^{P-1}\equiv 1 \pmod P\),即 \(a^\frac{P-1}{2}\equiv 1 \pmod P\)。
不存在二次剩余即 \(a^\frac{P-1}{2}\equiv -1\pmod P\)。
(对于所有 \(a=0,1\) 的情况需要特判)。
原根法求二次剩余
先求出 \(P\) 的一个原根 \(g\)。
那么可以用 \(g^k\) 表示出 \([1,P-1]\) 的所有数
用 \(\text{BSGS}\) 可以在 \(O(\sqrt n\log n)\) 的时间内求出 \(a=g^k\)。
如果存在原根,那么 \(k\mod 2=0\)。
答案就是 \(g^{\frac{k}{2}}\mod P\)。
1 | int BSGS(int a,int k=0) { |
更快的方法:Cipolla算法
要先找到一个数 \(y\),满足不存在 \(\sqrt{y^2-a}\pmod P\)。
可以随机 \(y\),期望可以两次找到这样的 \(y\)。
构造虚数 \(\omega = \sqrt{y^2-a}\),那么答案就是 \(x=\sqrt{y^2-\omega^2}=\sqrt{(y+\omega)(y-\omega)}\)。
然后构造复数 \((\alpha,\beta)=\alpha+\beta\omega\)。
求出 \(x=(y,1)^{\frac{(P+1)}{2}}\),模拟复数乘法即可。
可以证明结果没有虚部,就是答案。
1 | int Cipolla(int a,int k=0) { |