2019牛客暑期多校训练营(第九场)B Quadratic equation(欧拉准则+解二次剩余)

题目链接: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('\n')
 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 }
代码在这里!

猜你喜欢

转载自www.cnblogs.com/wuliking/p/11366852.html