B Quadratic equation 2019牛客多校第九场(二次剩余)

原题链接:
题意

\(已知(x+y)\) % \(p = b\) , \((x*y)\) % \(p = c\)\(\space\)求x , y.若不存在则输出\(-1\space-1\)


思路

\(通过平方差公式(x-y)^2\) = \((x+y)^2\) \(-\) \(4*(x+y)\) = \((b^2-4c)\) % \(p\),
\(我们就会想到二次剩余存在X^2\equiv d(mod\space p ) ,(d是模p的二次剩余) 来解得x-y,然后用b与(x-y)求出x,y\)
\(这里使用欧拉准则计算勒让德符号:\)
\(勒让德符号可以计算当p为素数的情况的二次剩余判别问题,而雅可比符号判定条件为a为任意整数,p为任意奇数\)
\(题目种给出的p为1000000007,是一个质数所以我们就用欧拉准则来做。\)
\(根据欧拉准则:当 a 是 mod\space p 的平方剩余时有 a^\frac{p-1}{2} \equiv \space1\) \((mod\space p)\space,当a不是平方剩余时a^\frac{p-1}{2} \equiv \space-1(mod\space p )\)
\(所以我们就用快速幂来求出(b^2-4c)^\frac{p-1}{2} 判断是否等于\space mod-1(无解情况),以及求出最后x,y的解。\)


(第一次使用markdown编辑不容易啊...)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll  mod  = 1000000007; 
ll q_pow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1)res=res*a % mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
int main(){
    int T;
    cin >> T;
    while(T--){
        ll b,c;
        cin >> b >> c;
        ll delta = (b * b - 4 * c  + mod) % mod;
        if(q_pow (delta,(mod - 1) / 2) == mod - 1) { puts("-1 -1"); continue; }
        ll a = q_pow (delta,((mod + 1) / 2 + 1) / 2);
        ll x = ((b - a + mod) * q_pow(2, mod - 2)) % mod;
        ll y = (b + mod - x) % mod;
        printf("%lld %lld\n", min(x,y),max(x,y));
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Tianwell/p/11366814.html