模版,以后直接套就好了
#include<bits/stdc++.h>
#define ll long long
#define random(a,b) (rand()%(b-a+1)+a)
using namespace std;
const ll mod = 1e9+7;
ll p = mod;
ll w;//二次域的D值
bool ok;//有无解
struct QuadraticField { //二次域
ll x,y;
QuadraticField operator*(QuadraticField T) {
QuadraticField ans;
ans.x = (this->x * T.x % p + this->y * T.y %p * w % p )% p;
ans.y = (this->x * T.y % p + this->y * T.x %p)% p;
return ans;
}
QuadraticField operator^(ll b) {
QuadraticField ans;
QuadraticField a = *this;
ans.x = 1;
ans.y = 0;
while(b) {
if(b&1) {
ans = ans*a;
b--;//!!!
}
b /= 2;
a = a*a;
}
return ans;
}
};
ll quick_mod(ll a,ll b,ll c) {
ll res = 1;
while(b) {
if(b&1) {
res = res*a%c;
}
b>>=1;
a = a*a%c;
}
return res;
}
ll Legender(ll a) { //求勒让德符号 -1不符合二次剩余 0和1符合
ll ans = quick_mod(a,(p-1)/2,p);
if(ans+1==p) { //如果ans的值为-1,%p之后会变成p-1
return -1;
} else {
return ans;
}
}
ll Getw(ll n,ll a) { //确定随机a所对应的w值
return(a*a%p-n+p)%p;
}
ll Solve(ll n) {
ll a;
if(p==2) { //当p为2的时候,n只会是0或1
return n;
}
if(Legender(n)==-1) {
ok = false;
}
srand((unsigned)time(NULL));
while(1) { //随机a的值直到有解
a = random(0,p-1);
w = Getw(n,a);
if(Legender(w)==-1) {
break;
}
}
QuadraticField ans,res;
res.x = a;
res.y = 1;//res = a + sqrt(w)
ans = res^((p+1)/2);
return ans.x;//返回a
}
int main() {
ll inv2 = quick_mod(2ll,mod-2,mod);
int t;
scanf("%d",&t);
while(t--) {
ll b,c;
scanf("%lld %lld",&b,&c);
ok = true;
ll tmp = (b*b-4*c+mod)%mod;
if(!tmp) {
printf("%lld %lld\n",b*inv2%mod,b*inv2%mod);
continue;
}
ll ans = Solve(tmp);
if(ok) {
ll x = (b+ans)*inv2%mod;
ll y = (b-ans+mod)*inv2%mod;
if((x+y)%mod == b && (x*y)%mod == c) {
if(x>y) swap(x,y);
printf("%lld %lld\n",x,y);
continue;
}
puts("-1 -1");
} else {
puts("-1 -1");
}
}
}