已知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;
} 
京公网安备 11010502036488号