1. 程式人生 > 實用技巧 >模板 求二次剩餘

模板 求二次剩餘

ll w;
struct num {
    ll x, y;
};

num mul(num a, num b, ll p)
{
    num ans = { 0,0 };
    ans.x = ((a.x * b.x % p + a.y * b.y % p * w % p) % p + p) % p;
    ans.y = ((a.x * b.y % p + a.y * b.x % p) % p + p) % p;
    return ans;
}

ll powwR(ll a, ll b, ll p) {
    ll ans = 1;
    while (b) {
        
if (b & 1)ans = 1ll * ans % p * a % p; a = a % p * a % p; b >>= 1; } return ans % p; } ll powwi(num a, ll b, ll p) { num ans = { 1,0 }; while (b) { if (b & 1)ans = mul(ans, a, p); a = mul(a, a, p); b >>= 1; } return ans.x % p; } ll solve(ll n, ll p) { n
%= p; if (p == 2)return n; if (powwR(n, (p - 1) / 2, p) == p - 1)return -1;//不存在 ll a; while (1) { a = rand() % p; w = ((a * a % p - n) % p + p) % p; if (powwR(w, (p - 1) / 2, p) == p - 1)break; } num x = { a,1 }; return powwi(x, (p + 1) / 2, p); }

-1 表示無解,否則兩個相同解或者一個解。