「学习笔记」二次剩余

说明:本文涉及变量除特殊说明外,全部属于整数集合。

前置芝士——二次剩余

二次剩余

当存在 \(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\)

  1. 随机一个 \(t\) ,满足 \(t^2-a\notin F_p\)
  2. \(\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\) 即可。

struct Z{
    uint x;
    Z(const uint _x=0):x(_x){}
    inline Z operator +(const Z &rhs)const{return x+rhs.x<MOD?x+rhs.x:x+rhs.x-MOD;}
    inline Z operator -(const Z &rhs)const{return x<rhs.x?x-rhs.x+MOD:x-rhs.x;}
    inline Z operator -()const{return x?MOD-x:0;}
    inline Z operator *(const Z &rhs)const{return (ull)x*rhs.x%MOD;}
    inline Z operator +=(const Z &rhs){return x=x+rhs.x<MOD?x+rhs.x:x+rhs.x-MOD,*this;}
    inline Z operator -=(const Z &rhs){return x=x<rhs.x?x-rhs.x+MOD:x-rhs.x,*this;}
    inline Z operator *=(const Z &rhs){return x=(ull)x*rhs.x%MOD,*this;}
    inline bool operator ==(const Z &rhs){return x==rhs.x;}
};
#define pzz pair<Z,Z>
inline pzz Mul(pzz x,pzz y,Z f){
//计算 a+bω 部分的 pzz 的乘法
    return mp(x.ft*y.ft+x.sd*y.sd*f,x.ft*y.sd+x.sd*y.ft);
}
inline Z Quadratic_residue(Z a){
//常数在模意义下的开根
    if(a.x<=1)return a.x;
    //使用欧拉定律判断有无解
    if(qkpow(a,(MOD-1)>>1).x!=1)return -1;
    Z x,f;
    //找到一个 x 使得 x^2 - a 不是二次剩余
    do x=(((ull)rand()<<15)^rand())%(a.x-1)+1;
    while(qkpow(f=x*x-a,(MOD-1)>>1)==Z(1));
    //初始变量
    pzz ans=mp(1,0),t=mp(x,1);
    //类似于快速幂
    for(uint i=(MOD+1)>>1;i>0;i>>=1,t=Mul(t,t,f))if(i&1)ans=Mul(ans,t,f);
    //返回较小根
    return Min(ans.ft.x,MOD-ans.ft.x);
}
posted @ 2019-12-25 18:17  南枙向暖  阅读(496)  评论(0编辑  收藏  举报