2019 cattle off more school ninth field B Quadratic equation (the quadratic residue theorem) solution to a problem

Meaning of the questions:

Portal
known \ (0 <= x <= y <p, p = 1e9 + 7 \) and has
\ ((X + Y) = B \ MOD P \)
\ ((X \ Y Times) = C \ mod p \)
solving any pair \ (X, Y \) , the output is not present \ (- 1 \ -1 \) .

Ideas:

The two formula variations available \ ((Y - X) ^ 2 = (P + B ^ 2 -4C) \% P \ MOD P \) , it can be appreciated that to obtain a given application of the quadratic residue \ (y - x \) values, we can know \ ((x + y) = b \) or \ ((the y-the X-+) = the p-b + \) , it can be directly solved.

Code:

#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 5e4 + 5;
const int INF = 0x3f3f3f3f;
const ull seed = 131;
const ll MOD = 1e9 + 7;
using namespace std;

ll ppow(ll a, ll b, ll mod){
    ll ret = 1;
    a = a % mod;
    while(b){
        if(b & 1) ret = ret * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ret;
}
struct TT{
    ll p, d;
};
ll w;
TT mul_er(TT a, TT b, ll mod){
    TT ans;
    ans.p = (a.p * b.p % mod + a.d * b.d % mod * w % mod) % mod;
    ans.d = (a.p * b.d % mod + a.d * b.p % mod) % mod;
    return ans;
}
TT power(TT a, ll b, ll mod){
    TT ret;
    ret.p = 1, ret.d = 0;
    while(b){
        if(b & 1) ret = mul_er(ret, a, mod);
        a = mul_er(a, a, mod);
        b >>= 1;
    }
    return ret;
}
ll legendre(ll a, ll p){
    return ppow(a, (p - 1) >> 1, p);
}
ll modulo(ll a, ll mod){
    a %= mod;
    if(a < 0) a += mod;
    return a;
}
ll solve(ll n, ll p){   //x^2 = n mod p
    if(n == 0) return 0;
    if(n == 1) return 1;
    if(p == 2) return 1;
    if(legendre(n, p) + 1 == p) return -1;  //无解
    ll a = -1, t;
    while(true){
        a = rand() % p;
        t = a * a - n;
        w = modulo(t, p);
        if(legendre(w, p) + 1 == p) break;
    }
    TT temp;
    temp.p = a;
    temp.d = 1;
    TT ans = power(temp, (p + 1) >> 1, p);
    return ans.p;
}
bool getans(ll sum, ll dec, ll &x, ll &y){
    if((sum + dec) % 2 == 0){
        y = (sum + dec) / 2;
        x = y - dec;
        if(x >= 0 && x + y == sum && y < MOD) return true;
        else return false;
    }
    else return false;
}
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        ll b, c;
        scanf("%lld%lld", &b, &c);
        ll d = solve((b * b % MOD - 4 * c % MOD + MOD) % MOD, MOD);
        if(d == -1){
            printf("-1 -1\n");
            continue;
        }
        ll x, y;
        if(getans(b, d, x, y)){
            printf("%lld %lld\n", x, y);
        }
        else if(getans(b + MOD, d, x, y)){
            printf("%lld %lld\n", x, y);
        }
        else if(getans(b, MOD - d, x, y)){
            printf("%lld %lld\n", x, y);
        }
        else if(getans(b + MOD, MOD - d, x, y)){
            printf("%lld %lld\n", x, y);
        }
    }
    return 0;
}


Guess you like

Origin www.cnblogs.com/KirinSB/p/11365909.html