已知0<=x<=y<p,p=1e9+7且有
(x+y)=bmodp
(x×y)=cmodp
求解任意一对x,y,不存在输出−1 −1。
由两式变化可得(y−x)2=(b2−4c+p)%p mod p,那么可以应用二次剩余定理解得y−x的值,我们可以知道(x+y)=b或者(x+y)=b+p,那么直接求解即可。
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; ll qpow_num(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1) { ans = (ans * a) % mod; } b >>= 1; a = (a * a) % mod; } return ans % mod; } pll qmul_pll(pll a, pll b, ll w, ll mod) { pll ans; ans.first = ((a.first * b.first) % mod + ((a.second * b.second) % mod * w) % mod) % mod; ans.second = ((a.second * b.first) % mod + (a.first * b.second) % mod) % mod; return ans; } pll qpow_pll(pll a, ll b, ll w, ll mod) { pll ans = make_pair(1, 0); while (b) { if (b & 1) { ans = qmul_pll(ans, a, w, mod); } a = qmul_pll(a, a, w, mod); b >>= 1; } return ans; } ll solve(ll n, ll mod) { n %= mod; if (n <= 1) return n; if (mod == 2) return n; if (qpow_num(n, (mod - 1) / 2, mod) == mod - 1) return -1; ll a, w; while (1) { a = rand()% mod; w = ((a * a - n) % mod + mod) % mod; if (qpow_num(w, (mod - 1) / 2, mod) == mod - 1) break; } pll ans = make_pair(a, 1); return qpow_pll(ans, (mod + 1) / 2, w, mod).first; } ll mod = 1000000007; ll getans(ll a, ll b, ll &x, ll &y) { if ((a + b) % 2 == 0) { y = (a + b) / 2; x = y - a; if (x >= 0 && y >= 0 && x < mod && y < mod) return true; } return false; } int main() { int T; srand(time(0)); cin >> T; while (T--) { ll b, c; cin >> b >> c; ll n = b * b - 4 * c + mod; n = (n % mod + mod) % mod; ll ans1 = solve(n, mod); if (ans1 == -1) { cout << "-1 -1" << endl; continue; } ll ans2 = mod - ans1; ll x, y; if (getans(ans1, b, x, y)) { cout << x << " " << y << endl; continue; } if (getans(ans1, b + mod, x, y)) { cout << x << " " << y << endl; continue; } if (getans(ans2, b, x, y)) { cout << x << " " << y << endl; continue; } if (getans(ans2, b + mod, x, y)) { cout << x << " " << y << endl; continue; } cout << "-1 -1" << endl; } return 0; }