• 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
    ",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 }
  • 相关阅读:
    内存泄露之LeakCanary原理简析
    springboot(2.3.4)替换默认的logback为log4j2
    springboot-SPI-修改配置文件
    Vue组件
    米尔开发板测试记录
    调试米尔开发板记录
    linux操作GPIO命令
    linux操作PWM命令
    前端缓存(Storage)之有效期
    微信移动端判断二维码识别是否长按
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/11682025.html
Copyright © 2020-2023  润新知