【算法讲18:二次剩余】勒让德符号 | 欧拉判别法 | Cipolla 算法

S o u r c e \mathfrak{Source} Source

  • 《初等数论及其应用》第六版第十一章
    省略了很多帮助理解的例子和证明。浓缩了一下密集的知识点。
    Cipolla算法学习小记 [ 1 ]

⌈ \lceil 二次剩余 ⌋ \rfloor ⌈ \lceil 二次非剩余 ⌋ \rfloor

  • 定义:
    m m m 是正整数, a a a 是整数,若 ( a , m ) = 1 (a,m)=1 (a,m)=1,且同余方程 x 2 ≡ a ( m o d m ) x^2\equiv a\pmod m x2a(modm) 有解,则称 a a a m m m二次剩余
    若同余方程 x 2 ≡ a ( m o d m ) x^2\equiv a\pmod m x2a(modm) 无解,则称 a a a m m m二次非剩余
  • 引理 11.1 11.1 11.1
    p p p奇素数 a a a 是不被 p p p 整除的整数,则同余方程
    x 2 ≡ a ( m o d p ) x^2\equiv a\pmod p x2a(modp)
    或者无解,或者恰有两个模 p p p 不同余的解。
    证明:(1)若该同余方程有解,不妨设 x = x 0 x=x_0 x=x0,易得 x = − x 0 x=-x_0 x=x0 是不同余的解。
    (2)为证不存在多于两个不同余的解,设 x 0 x_0 x0 x 1 x_1 x1 都是该同余方程的解。
    则有 x 0 2 = x 1 2 ≡ a ( m o d p ) x_0^2=x_1^2\equiv a\pmod p x02=x12a(modp),于是 x 0 2 − x 1 2 = ( x 0 + x 1 ) ( x 0 − x 1 ) ≡ 0 ( m o d p ) x_0^2-x_1^2=(x_0+x_1)(x_0-x_1)\equiv 0\pmod p x02x12=(x0+x1)(x0x1)0(modp)
    因此 p ∣ ( x 0 + x 1 ) p|(x_0+x_1) p(x0+x1) p ∣ ( x 0 − x 1 ) p|(x_0-x_1) p(x0x1),于是 x 1 ≡ − x 0 ( m o d p ) x_1\equiv -x_0\pmod p x1x0(modp) 或者 x 1 ≡ x 0 ( m o d p ) x_1\equiv x_0\pmod p x1x0(modp).
    因此,若 x 2 ≡ a ( m o d p ) x_2\equiv a\pmod p x2a(modp),则只能有两个不同余的解。
  • 定理 11.1 11.1 11.1
    p p p 是奇素数,则在整数 1 , 2 , ⋯   , p − 1 1,2,\cdots,p-1 1,2,,p1 中, p p p 的二次剩余恰有 ( p − 1 ) / 2 (p-1)/2 (p1)/2个,二次非剩余恰有 ( p − 1 ) / 2 (p-1)/2 (p1)/2 个。
  • 勒让德符号
    p p p 是奇素数,整数 a a a 不被 p p p 整除,勒让德符号定义为:
    ( a p ) = { 1 若 a 是 p 的 二 次 剩 余 − 1 若 a 是 p 的 二 次 非 剩 余 (\frac{a}{p})= \begin{cases} 1&若 a是p的二次剩余\\ -1&若a是p的二次非剩余\\ \end{cases} (pa)={11apap
  • 欧拉判别法
    p p p 是奇素数, a a a 是不被 p p p 整除的正整数,则
    ( a p ) ≡ a ( p − 1 ) / 2 ( m o d p ) (\frac{a}{p})\equiv a^{(p-1)/2}\pmod p (pa)a(p1)/2(modp)
    证明:(1)首先假设 ( a p ) = 1 (\frac{a}{p})=1 (pa)=1,于是同余方程 x a ≡ a ( m o d p ) x^a\equiv a\pmod p xaa(modp) 有解,设为 x = x 0 x=x_0 x=x0
    利用费马小定理,可知
    a ( p − 1 ) / 2 = ( x 0 2 ) ( p − 1 ) / 2 = x 0 p − 1 ≡ 1 ( m o d p ) a^{(p-1)/2}=(x_0^2)^{(p-1)/2}=x_0^{p-1}\equiv 1\pmod p a(p1)/2=(x02)(p1)/2=x0p11(modp)
    因此,若 ( a p ) = 1 (\frac{a}{p})=1 (pa)=1,则 ( a p ) ≡ a ( p − 1 ) / 2 ( m o d p ) (\frac{a}{p})\equiv a^{(p-1)/2}\pmod p (pa)a(p1)/2(modp)
    (2)现在考虑 ( a p ) = − 1 (\frac{a}{p})=-1 (pa)=1,此时同余方程 x a ≡ a ( m o d p ) x^a\equiv a\pmod p xaa(modp) 无解。
    此时对每个满足 ( i , p ) = 1 (i,p)=1 (i,p)=1 的整数 i i i,存在整数 j j j 使得 i j ≡ a ( m o d p ) ij\equiv a\pmod p ija(modp),且 i ≠ j i\ne j i=j
    因此,我们可以将整数 1 , 2 , ⋯   , p − 1 1,2,\cdots,p-1 1,2,,p1 分成 ( p − 1 ) / 2 (p-1)/2 (p1)/2 对,每一对的乘积为 a a a,将这些相乘得到
    ( p − 1 ) ! ≡ a ( p − 1 ) / 2 ( m o d p ) (p-1)!\equiv a^{(p-1)/2}\pmod p (p1)!a(p1)/2(modp)
    由威尔逊定理可知 ( p − 1 ) ! ≡ − 1 ( m o d p ) (p-1)!\equiv -1\pmod p (p1)!1(modp)
    于是 a ( p − 1 ) / 2 ≡ − 1 ( m o d p ) a^{(p-1)/2}\equiv -1\pmod p a(p1)/21(modp)
    于是,我们得到了 ( a p ) ≡ a ( p − 1 ) / 2 ( m o d p ) (\frac{a}{p})\equiv a^{(p-1)/2}\pmod p (pa)a(p1)/2(modp)
  • 定理 11.4 11.4 11.4
    p p p 是奇素数, a a a b b b 是不被 p p p 整除的整数,则
    ( 1 ) 若 a ≡ b ( m o d p ) , 则 ( a p ) = ( b p ) ( 2 ) ( a p ) ( b p ) = ( a b p ) ( 3 ) ( a 2 p ) = 1 \begin{aligned} &(1)若 a\equiv b\pmod p,则 (\frac{a}{p})=(\frac{b}{p})\\ &(2)(\frac{a}{p})(\frac{b}{p})=(\frac{ab}{p})\\ &(3)(\frac{a^2}{p})=1 \end{aligned} (1)ab(modp)(pa)=(pb)(2)(pa)(pb)=(pab)(3)(pa2)=1
  • 高斯引理
    p p p 是奇素数, a a a 是整数,且 ( a , p ) = 1 (a,p)=1 (a,p)=1.
    s s s 是整数 a , 2 a , 3 a , ⋯   , ( p − 1 2 ) a a,2a,3a,\cdots,(\frac{p-1}{2})a a,2a,3a,,(2p1)a 的最小正剩余中大于 p 2 \frac{p}{2} 2p 的个数
    ( a p ) = ( − 1 ) s (\frac{a}{p})=(-1)^s (pa)=(1)s
    证明略。

⌈ \lceil 二次互反律 ⌋ \rfloor

  • 二次互反律
    p , q p,q pq 是不同的奇素数,则
    ( p q ) ( q p ) = ( − 1 ) p − 1 2 ⋅ q − 1 2 (\frac{p}{q})(\frac{q}{p})=(-1)^{\frac{p-1}{2}\cdot\frac{q-1}{2}} (qp)(pq)=(1)2p12q1

⌈ C i p o l l a ⌋ \lceil\mathfrak{Cipolla}\rfloor Cipolla 算法

引入

  • 【模板】二次剩余 | 洛谷 P5491
    给定 N 、 p N、p Np,求解 x 2 ≡ N ( m o d p ) x^2\equiv N\pmod p x2N(modp)
    其中 p p p 是奇素数。
    样例组数 T ≤ 1000 T\le 1000 T1000
    N , p ≤ 1 0 9 + 9 N,p\le 10^9+9 N,p109+9

C i p o l l a Cipolla Cipolla 算法

  • 第一步
    随机找一个 a ∈ [ 0 , p ) a\in[0,p) a[0,p),使得其满足 ( a 2 − n ) ( p − 1 ) / 2 ≡ − 1 ( m o d p ) (a^2-n)^{(p-1)/2}\equiv -1\pmod p (a2n)(p1)/21(modp)
    根据定理 11.1 11.1 11.1,期望次数为 2 2 2
  • 第二步
    设一个复数 ω = a 2 − n \omega=\sqrt{a^2-n} ω=a2n ,易得满足 ω 2 = a 2 − n \omega^2=a^2-n ω2=a2n
  • 第三步
    最终答案为 x 0 = ( a + ω ) ( p + 1 ) / 2 x_0=(a+\omega)^{(p+1)/2} x0=(a+ω)(p+1)/2
    根据引理 11.1 11.1 11.1,另一个不同余的答案为 x 1 ≡ − x 0 ( m o d p ) x_1\equiv -x_0\pmod p x1x0(modp)

C i p o l l a Cipolla Cipolla 算法的证明

  • 参考 [ 1 ] 处的博客。
  • 引理 1 1 1
    ( a + b ) p ≡ a p + b p ( m o d p ) (a+b)^p\equiv a^p+b^p\pmod p (a+b)pap+bp(modp)
    证明:展开二项式之后可以得到
    ( a + b ) p = ∑ i = 0 p C p i a i b p − i = ∑ i = 0 p p ! i ! ( p − i ! ) a i b p − i ≡ a p + b p ( m o d p ) (a+b)^p=\sum_{i=0}^pC_p^ia^ib^{p-i}=\sum_{i=0}^p\frac{p!}{i!(p-i!)}a^ib^{p-i}\equiv a^p+b^p\pmod p (a+b)p=i=0pCpiaibpi=i=0pi!(pi!)p!aibpiap+bp(modp)
  • 引理 2 2 2
    ω p ≡ − ω ( m o d p ) \omega^p\equiv -\omega \pmod p ωpω(modp)
    证明:
    ω p = ω p − 1 × ω = ( ω 2 ) ( p − 1 ) / 2 × ω = ( a 2 − n ) ( p − 1 ) / 2 × ω ≡ − ω ( m o d p ) \begin{aligned} \omega^p&=\omega^{p-1}\times\omega\\ &=(\omega^2)^{(p-1)/2}\times\omega\\ &=(a^2-n)^{(p-1)/2}\times \omega\\ &\equiv -\omega \pmod p \end{aligned} ωp=ωp1×ω=(ω2)(p1)/2×ω=(a2n)(p1)/2×ωω(modp)
  • 引理 3 3 3
    a p ≡ a ( m o d p ) a^p\equiv a\pmod p apa(modp)
    证明:根据费马小定理得到 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1\pmod p ap11(modp) 可得。
  • 推导
    以下同余式子皆为 ( m o d p ) \pmod p (modp) 意义下成立的。
    ( a + ω ) ( p + 1 ) / 2 ≡ ( ( a + ω ) p ( a + ω ) ) 1 / 2 ≡ ( ( a p + ω p ) ( a + ω ) ) 1 / 2 根 据 引 理 1 ≡ ( ( a − ω ) ( a + ω ) ) 1 / 2 根 据 引 理 2 和 3 ≡ ( a 2 − ω 2 ) 1 / 2 ≡ ( a 2 − a 2 + n ) 1 / 2 ≡ n 1 / 2 \begin{aligned} (a+\omega)^{(p+1)/2}&\equiv ((a+\omega)^p(a+\omega))^{1/2}\\ &\equiv ((a^p+\omega^p)(a+\omega))^{1/2}&根据引理1\\ &\equiv ((a-\omega)(a+\omega))^{1/2}&根据引理2和3\\ &\equiv (a^2-\omega^2)^{1/2}\\ &\equiv (a^2-a^2+n)^{1/2}\\ &\equiv n^{1/2} \end{aligned} (a+ω)(p+1)/2((a+ω)p(a+ω))1/2((ap+ωp)(a+ω))1/2((aω)(a+ω))1/2(a2ω2)1/2(a2a2+n)1/2n1/2123

代码中怎么求 ( a + ω ) ( p + 1 ) / 2 (a+\omega)^{(p+1)/2} (a+ω)(p+1)/2

  • 由于我们已知 ω 2 = a 2 − n \omega^2=a^2-n ω2=a2n,我们可以把 ω \omega ω 看成虚部,然后
    ( a 1 + b 1 ω ) ( a 2 + b 2 ω ) = ( a 1 a 2 + b 1 b 2 ω 2 ) + ( a 1 b 2 + a 2 b 1 ) ω (a_1+b_1\omega)(a_2+b_2\omega)=(a_1a_2+b_1b_2\omega^2)+(a_1b_2+a_2b_1)\omega (a1+b1ω)(a2+b2ω)=(a1a2+b1b2ω2)+(a1b2+a2b1)ω
    然后用复数快速幂即可。

代码

  • 时间复杂度: O ( T log ⁡ n ) O(T\log n) O(Tlogn)
const int MAX = 1e6+50;

ll qpow(ll a,ll n,ll p){a%=p;ll res = 1LL;while(n){if(n&1)res=res*a%p;a=a*a%p;n>>=1;}return res;}

struct comp{
    ll x,y;
    comp(ll xx = 0,ll yy = 0){x = xx,y = yy;}
};
ll omega;
comp mul(comp a,comp b,ll p){
    comp c = {0,0};
    c.x = a.x * b.x % p + a.y * b.y % p * omega % p;
    c.y = a.x * b.y % p + a.y * b.x % p;
    c.x = (c.x % p + p) % p;
    c.y = (c.y % p + p) % p;
    return c;
}
ll qpow(comp a,ll n,ll p){
    comp res = {1,0};
    while(n){
        if(n & 1)res = mul(res,a,p);
        a = mul(a,a,p);
        n >>= 1;
    }
    return res.x;
}

bool Eular(ll n,ll p){
    return qpow(n,(p-1)/2,p) == 1;
}
ll quad_residue(ll n,ll p){
    n %= p;
    if(!Eular(n,p))return -1;
    ll a = 0;
    while(1){
        a = rand() % p;
        omega = ((a * a % p - n) % p + p) % p;
        if(qpow(omega,(p-1)/2,p) == p-1){
            break;
        }
    }
    comp I = {a,1};
    return qpow(I,(p+1)/2,p);
}
int main()
{
    int T;scanf("%d",&T);
    while(T--){
        ll n,p;
        scanf("%lld%lld",&n,&p);
        if(n == 0){
            puts("0");
            continue;
        }

        ll ans1 = quad_residue(n,p);
        ll ans2 = p - ans1;
        if(ans1 == -1){
            puts("Hola!");
            continue;
        }
        if(ans1 > ans2)swap(ans1,ans2);
        printf("%lld %lld\n",ans1,ans2);
    }
    return 0;
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值