目录
- 前置芝士——二次剩余
- 二次剩余
- 二次剩余的个数
- 欧拉准则
- 过程
- 定理一
- 定理二
- 定理三
- 证明
- 关于 ω
- 代码实现
说明:本文涉及变量除特殊说明外,全部属于整数集合。
前置芝士——二次剩余
二次剩余
当存在 \(x\) 使得 \(x^2\equiv a\pmod{p}\) ,那么我们称 \(a\) 是取模 \(p\) 的二次剩余(Quadratic residue)。
对于一个奇素数 \(p\) ,定义它的二次剩余集合为 \(F_p\) ,并且对于其中每一个数 \(n\) 满足 \(\exists x\in [0,p),x^x\equiv n\pmod{p}\) 。
二次剩余的个数
对于前面定义的集合,有 \(\mid F_p \mid=\frac{p+1}{2}\) ,证明如下:
令 \(u^2\equiv v^2\equiv n\pmod{p},u\neq v\) ,那么
\[ \begin{aligned} p&\mid (u^2-v^2)\\ \Longrightarrow p&\mid (u-v)(u+v) \end{aligned} \]
显然,若 \(p\mid (u-v)\) ,因为 \(p\) 为奇素数,那么 \(u-v=p\) ,但这是不可能满足的。
即一定有 \(p\nmid (u-v)\) ,那么就有 \(p\mid (u+v)\) ,同理, \(u+v=p\) 。
即在 \(u,v\in [0,p)\) 的范围中,除 \(0\) 以外,其他的数两两对应。
那么个数就是 \(\frac{p-1}{2}+1=\frac{p+1}{2}\) ,证毕。
欧拉准则
用来判定一个非零数是否是二次剩余。
对于一个 \(d\) 满足 \((d,p)=1,d>0\) ,那么一定满足
\[ d^{\frac{p-1}{2}}\pmod{p}=\left \{ \begin{aligned} 1,d&\in F_p\\ -1,d&\notin F_p \end{aligned} \right. \]
证明:
根据费马小定理,一定有
\[ \begin{aligned} d^{p-1}-1&\equiv 0&\pmod p\\ \Longrightarrow(d^{\frac{p-1}{2}}-1)(d^{\frac{p-1}{2}}+1)&\equiv 0&\pmod p \end{aligned} \]
若 \(\exists x,x^2\equiv d\pmod p\) ,那么就有 \(d^{\frac{p-1}{2}}\equiv x^{p-1}\pmod p\) 。
那么,就有满足 \(d\in F_p\) 时,有 \(d^{\frac{p-1}{2}}\equiv 1\pmod{p}\) 。
过程
现在我们要求一个 \(x\) 满足
\[ x^2\equiv a\pmod p \]
用以下步骤可求得 \(x\) 。
- 随机一个 \(t\) ,满足 \(t^2-a\notin F_p\) 。
- 令 \(\omega =\sqrt{t^2-a}\) ,则 \(x=(t+\omega)^{\frac{p+1}{2}}\)
证明过程需要几个小定理...
定理一
- 内容:
\[ (a+b)^p\equiv a^p+b^p\pmod p \tag{1} \]
- 证明:
\[ (a+b)^p=\sum_{i=0}^p\binom{p}{i}a^ib^{p-i} \]
当 \(i\neq 0\) 且 \(i\neq p\) ,满足 \(\binom{p}{i}\equiv 0\pmod p\) 。
定理二
- 内容:
\[ \omega^p\equiv-\omega \pmod{p} \tag{2} \]
- 证明:
因为 \(t^2-a\notin F_p\) ,所以满足
\[ \omega^{p-1}=(\omega^2)^{\frac{p-1}{2}}=(t^2-a)^{\frac{p-1}{2}}\equiv-1 \pmod{p} \]
定理三
- 内容:
\[ (a+\omega)^p\equiv a-\omega \pmod{p} \tag{3} \]
由 \((1)、(2)\) 显然。
证明
由前面的定理可知
\[ \begin{aligned} x^2&=(t+\omega)^{p+1} \\ &=(t+\omega)(t+\omega)^p \\ &\equiv (t+\omega)(t-\omega) \pmod{p}\\ &=t^2-\omega^2 \\ &=t^2-(t^2-a) \\ &=a \end{aligned} \]
关于 ω
方程 \(x^2-a=0\) 在任何域中都有两个根(由勒让德定理),并且并且我们前面得到了这两个根都在模 \(p\) 的剩余系中,所以没有 \(\omega\) 。
代码实现
代码处理的时候,只需要记录公式中 \(a+b\omega\) 的两个系数 \(a、b\) 即可。
inline int Pow(ll x, int y=P-2){
int ans=1;
for(; y; y>>=1, x=x*x%P) if(y&1) ans=ans*x%P;
return ans;
}
inline pair pMul(pair x, pair y, int f){
return make_pair(
(int)(((ll)x.first*y.first+(ll)x.second*y.second%P*f)%P),
(int)(((ll)x.second*y.first+(ll)x.first*y.second)%P)
);
}
inline int Quadratic_residue(int a){
if(Pow(a, (P-1)/2)!=1) return -1;
int x, f;
do x=(((ll)rand()<<15)^rand())%(a-1)+1; while(Pow(f=((ll)x*x-a+P)%P, (P-1)/2)==1);
pair ans=make_pair(1, 0), t=make_pair(x, 1);
for(int i=(P+1)/2; i; i>>=1, t=pMul(t, t, f)) if(i&1) ans=pMul(ans, t, f);
return min(ans.first, P-ans.first);
}