Loading

二次剩余

概念

\(\forall c \in N^+\),如果 \(\exists x^2 \equiv c \pmod p\),则称 \(c\) 是模 \(p\) 的二次剩余。

对于 \(p\) 是奇质数的情况,有简单的方法求出同余方程 \(x^2 \equiv c \pmod p\) 的解。

思路

结论:

  • 当且仅当 \(c^{\frac{p - 1}{2}} = 1\)\(c\) 是模 \(p\) 的二次剩余。

  • \(p\) 意义下的二次剩余有 \(\frac{p - 1}{2}\) 个。

证明可能是伪证,就不放了。

根据结论可以导出 Cipolla 算法。

首先需要找出一个同余系中的数 \(a\) 使得 \(a^2 - c\) 是非二次剩余。

对于同余方程 \(x^2 \equiv c \pmod p\),因为非二次剩余的数量在 \(\frac{p}{2}\) 左右,所以随机检验数的方式可以在期望 \(2\) 次的时间内找到一个 \(a\).

定义 \(i^2 \equiv a^2 - c \pmod p\),这里 \(i\) 不是同余系中的数,可以认为是虚数。

此时有结论:\((a + i)^{p + 1} \equiv c \pmod p\),并且 \((a + i)^{p + 1}\) 的虚部恰为 \(0\).

证明不太会,咕了。

直接写个复数类实现就行。

代码

#include <cstdio>
#include <ctime>
#include <cstdlib>
using namespace std;

#define swap(x, y) x ^= y ^= x ^= y

typedef long long ll;

int t, mod, c;
ll Ipw2;

struct cpx
{
    ll real, imag;

    cpx operator * (const cpx& rhs) const { return (cpx){(real * rhs.real + imag * rhs.imag % mod * Ipw2) % mod, (real * rhs.imag + imag * rhs.real) % mod}; }
} ;

int qpow(int base, int power)
{
    int res = 1;
    while (power)
    {
        if (power & 1) res = 1ll * res * base % mod;
        base = 1ll * base * base % mod, power >>= 1;
    }
    return res;
}

cpx qpow(cpx base, int power)
{
    cpx res = (cpx){1, 0};
    while (power)
    {
        if (power & 1) res = res * base;
        base = base * base, power >>= 1;
    }
    return res;
}

int main()
{
    srand(time(0));
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d%d", &c, &mod);
        if (c == 0) { puts("0"); continue; }
        if (qpow(c, (mod - 1) / 2) == mod - 1) { puts("Hola!"); continue; }
        int a;
        while (true)
        {
            a = (rand() % (mod - 1) + mod) % (mod - 1) + 1;
            Ipw2 = (1ll * a * a - c + mod) % mod;
            if (qpow(Ipw2, (mod - 1) / 2) == mod - 1)
            {
                cpx w = (cpx){a, 1};
                w = qpow(w, (mod + 1) / 2);
                ll r1 = w.real, r2 = mod - w.real;
                if (r1 > r2) swap(r1, r2);
                printf("%lld %lld\n", r1, r2);
                break;
            }
        }
    }
    return 0;
}
posted @ 2023-02-11 16:09  kymru  阅读(45)  评论(0)    收藏  举报