题目链接:https://ac.nowcoder.com/acm/contest/889/B
题目大意:
给出b,c,让你求x,y,x和y满足(x+y)%p=c和(x*y)%p=c。
解题报告:
根据题目两个式子,可以化成$(x-y)^{2}=(x+y)^{2}-4xy$,所以只需计算$(x-y)^{2}=b^{2}-4c(mod p)$的二次剩余
对n是否为mod p的二次剩余的判断,可以用欧拉准则。欧拉准则的判断戳这里。
接着发现p恰好满足Tonelli_shanks算法的第一点,所以直接套第一点即可,最后就是解方程了。二次剩余系解法戳这里.
AC代码:
1 #include<bits/stdc++.h> 2 #define numm ch-48 3 #define pd putchar(' ') 4 #define pn putchar(' ') 5 using namespace std; 6 template <typename T> 7 void read(T &res) { 8 bool flag=false;char ch; 9 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 10 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 11 flag&&(res=-res); 12 } 13 template <typename T> 14 void write(T x) { 15 if(x<0) putchar('-'),x=-x; 16 if(x>9) write(x/10); 17 putchar(x%10+'0'); 18 } 19 typedef long long ll; 20 const int mod=1e9+7; 21 const int inv2=500000004; 22 ll ksm(ll a,ll b) { 23 ll ans=1; 24 while(b) { 25 if(b&1) ans=ans*a%mod; 26 b>>=1; 27 a=a*a%mod; 28 } 29 return ans; 30 } 31 int main() 32 { 33 int _; 34 read(_); 35 while(_--){ 36 ll b,c; 37 read(b),read(c); 38 ll dr=((b*b-4*c)%mod+mod)%mod; ///方程右边 39 if(ksm(dr,(mod-1)/2)==mod-1) { ///欧拉准则判断dr是否是二次剩余 40 write(-1),pd,write(-1);pn; 41 continue; 42 } 43 ll R=ksm(dr,(mod+1)/4); ///解 44 ll f1=((b-R)%mod+mod)%mod,f2=((b+R)%mod+mod)%mod; 45 f1=f1*inv2%mod,f2=f2*inv2%mod; 46 write(min(f1,f2)),pd,write(max(f1,f2));pn; 47 } 48 return 0; 49 }