[二次剩余]求解二次剩余

Description

求解 x2n(modp) p 是一个奇质数。

Solution

由费马小定理

np11(modp)
所以
np12±1(modp)
由欧拉准则
(np)np12(modp)
其中
(np)
为勒让德符号。因为 xn12(modp) ,所以有 xp1np121(modp) 。即
(np)=110npnpn0(modp)
k=a2n,ω=k
则该方程的解为
x(a+ω)p+12(modp)
证明:若 k 是该模意义下的非二次剩余,则
wp1=np12=1
同时:
(a+b)pap+bp(modp)
x21(a+ω)p+1(a+ω)p(a+ω)(ap+ωp)(a+ω)(ap1a+ωp1ω)(a+ω)(aω)(a+ω)a2ω2a2(a2n)n(modp)
另一解为
x2x1(modp)

如何找到这个 k 呢。因为非二次剩余的个数大约有一半,随机几次即可。
后面去实现了一下,发现要重新定义一个复数域 Fp2 ,然后就好啦。

struct Complex {
    ll r, i;
    Complex(ll _r = 0, ll _i = 0):r(_r), i(_i) {}
    inline Complex operator +(ll x) {
        return Complex((x + r) % P, i);
    }
    inline Complex operator *(Complex a) {
        ll rr = (a.r * r % P + w * a.i % P * i % P + P * 3) % P,
            ii = (a.i * r % P + a.r * i % P) % P;
        return Complex(rr, ii);
    }
};

inline ll Qr(ll x, ll p) {
    if (Pow(x, (P - 1) / 2) == P - 1) return -1;
    if (Pow(x, (P - 1) / 2) == 0) return 0;
    ll a;
    Complex k(0, 1);
    while (true) {
        a = rand();
        if (Pow((a * a - x + P) % P, (P - 1) / 2) == P - 1) break;
    }
    w = (a * a - x + P) % P;
    return Pow(k + a, (P + 1) / 2);
}

你可能感兴趣的:(数论,二次剩余,Notes)