题意:给定p=1e9+7,A,B。 求一对X,Y,满足(X+Y)%P=A; 且(X*Y)%P=B;
思路:即,X^2-BX+CΞ0; 那么X=[B+-sqrt(B^2-4C)]/2;
全部部分都要在modP意义下,所以求一个x满足x^2%p=B^2-4C,这个用二次剩余求即可。
套了模板。
#include <bits/stdc++.h> using namespace std; const int mod=1e9+7; typedef long long ll; int k; ll a,p,w; struct T{ll x,y;}; T mul_two(T a,T b,ll p) { T ans; ans.x=(a.x*b.x%p+a.y*b.y%p*w%p)%p; ans.y=(a.x*b.y%p+a.y*b.x%p)%p; return ans; } T qpow_two(T a,ll n,ll p) { T ans; ans.x=1; ans.y=0; while(n){ if(n&1) ans=mul_two(ans,a,p); n>>=1; a=mul_two(a,a,p); } return ans; } ll qpow(ll a,ll n,ll p) { ll ans=1; a%=p; while(n){ if(n&1) ans=ans*a%p; n>>=1;a=a*a%p; } return ans%p; } ll Legendre(ll a,ll p) { return qpow(a,(p-1)>>1,p); } int solve(ll n,ll p) { n%=p; if(p==2) return 1; if(Legendre(n,p)+1==p) return -1; else if(n==0) return 0; ll a=1; while(Legendre((a*a-n+p)%p,p)+1!=p) a=rand()%p; T tmp; tmp.x=a; tmp.y=1; w=(a*a-n+p)%p;//W T ans=qpow_two(tmp,(p+1)>>1,p); return ans.x; } int main() { scanf("%d",&k); ll rev2=500000004; while(k--){ ll b,c; scanf("%lld%lld",&b,&c); ll t=((b*b-c*4)%mod+mod)%mod; ll d=solve(t,mod); if(d==-1){ printf("-1 -1 "); continue; } ll x=(b+d)*rev2%mod,y=(b-x+mod)%mod; if(x>y) swap(x,y); printf("%lld %lld ",x,y); } return 0; }