2019牛客多校第九场 B.Quadratic equation

传送:https://ac.nowcoder.com/acm/contest/889/B

题意:

已知方程组:

$(x+y) mod p=b$

$(x*y) mod p=c$。

现在给出$b,c$,$p=1e9+7$。求解$x,y(x<=y)$。

分析:

先不考虑取模的条件。那么两个等式求解两个变量,可以化为一元二次方程:$b^2-4*c={x-y}^2$。

那么等于就是求解这样一个式子:$t^2=b^2-4*c$。(同时有取模)

 

用的是陈老师的板子。

那么求解出对于方程的两个解$ans1,ans2$。此时这两个解是$|x-y|$。那么就需要枚举两种,和为$b$或者$b+mod$。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 using namespace std;
 5 typedef long long ll;
 6 const ll mod=1e9+7;
 7 ll pow_mod(ll x,ll y,ll mod){
 8     ll res=1,base=x;
 9     while (y){
10         if (y&1) (res*=base)%=mod;
11         (base*=base)%=mod;
12         y>>=1;
13     }
14     return res;
15 }
16 ll b,c,ans1,ans2;
17 ll work(ll n, ll p) {
18     if (n == 0){  //特判x=y 
19         ans1=0;ans2=p-ans1;
20         return ans1;
21     }
22     //if (p == 2) return (n & 1) ? 1 : -1;
23     if (pow_mod(n, p >> 1, p) != 1) return -1;
24     if (p & 2){
25         ans1=pow_mod(n, p + 1 >> 2, p);ans2=p-ans1;
26         return ans1;
27     }
28     int s = __builtin_ctzll(p ^ 1);
29     ll q = p >> s, z = 2;
30     for (; pow_mod(z, p >> 1, p) == 1; ++z);
31     ll c = pow_mod(z, q, p);
32     ll r = pow_mod(n, q + 1 >> 1, p);
33     ll t = pow_mod(n, q, p), tmp;
34     for (int m = s, i; t != 1;) {
35         for (i = 0, tmp = t; tmp != 1; ++i) tmp = tmp * tmp % p;
36         for (; i < --m;) c = c * c % p;
37         r = r * c % p;
38         c = c * c % p;
39         t = t * c % p;
40     }
41     ans1=r; ans2=p-r;
42     return r;
43 }
44 bool solve(ll del,ll sum){  //del=|x-y|,sum=x+y 
45     int f1=(del&1),f2=(sum&1);  //奇偶性相同 
46     if(f1!=f2) return false;
47     ll x=(del+sum)/2,y=(sum-del)/2;
48     if(x>y) swap(x,y);
49     if((x+y)%mod!=b||(x*y)%mod!=c) return 0;
50     if(!(x>=0&&x<mod&&y>=0&&y<mod)) return 0;
51     printf("%lld %lld\n",x,y);
52     return 1;
53 }
54 int main()
55 {
56     int T;scanf("%d",&T);
57     while(T--)
58     {
59         scanf("%lld%lld",&b,&c);
60         ll t=((b*b-4*c)%mod+mod)%mod;
61         if(work(t,mod)==-1) {puts("-1 -1");continue;}
62         int flag=0;
63         flag=solve(ans1,b);if(flag) continue;   //和为b或b+mod 
64         flag=solve(ans1,mod+b);if(flag) continue;
65         flag=solve(ans2,b);if(flag) continue;
66         flag=solve(ans2,mod+b);if(flag) continue;
67         if(!flag) puts("-1 -1");
68     }
69 }

 

posted @ 2019-10-16 00:03  Changer-qyz  阅读(17)  评论(0编辑  收藏