码迷,mamicode.com
首页 > 其他好文 > 详细

方程的解(exgcd模板)

时间:2019-07-24 09:31:52      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:read   tin   回顾   alt   vector   枚举   rac   img   hid   

题面在考试反思中。

题解:

  这题其实只是个板子题,但考试时忘记了,又不会推导,于是凉凉。。。

  借这道题回顾一下$ exgcd $的各种特判:

  我习惯将方程$ ax+by=c $看成一次函数$ y=-\frac{a}{b}x+\frac{c}{b} $

  而在此之前我们要特判b是否为0,再根据一次函数的性质来判断。

  $ a,b,c $都为0时,无数组解。

  $ a,b $为0且$ c $不为0时,无解

  $ b=0 $时,若$ a*c<0 $,无正整数解。

        若$ c\%a=0 $,无数组解。

  $b$不为0时,若$ a=0 $时,同$b$。

        若$ a*b<0 $时,判断是否有无穷解,若否则为无正整数解。

        若$ a*b>0 $时,分三种情况:

            $ c=0 $时,无正整数解。

            $ c*b<0 $时,无正整数解。

            $ c*b>0 $时,需我们进行求解。

  而求解时我们不需枚举每个解,只需算出最大解及最小解即可,

 

代码:

技术图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<vector>
 6 #include<algorithm>
 7 using namespace std;
 8 #define R register
 9 #define ll long long
10 inline ll read(){
11     ll aa=0;R int bb=1;char cc=getchar();
12     while(cc<0||cc>9)
13         {if(cc==-)bb=-1;cc=getchar();}
14     while(cc>=0&&cc<=9)
15         {aa=(aa<<1)+(aa<<3)+(cc^48);cc=getchar();}
16     return aa*bb;
17 }
18 const int lim=65535;
19 ll exgcd(ll a,ll b,ll &x,ll &y)
20 {
21     if(!b){x=1;y=0;return a;}
22     ll d=exgcd(b,a%b,x,y);
23     ll z=x;x=y;y=z-y*(a/b);
24     return d;
25 }
26 ll T,a,b,c;//6
27 inline bool solve(ll &x,ll &y)
28 {
29     ll gcd=exgcd(a,b,x,y);
30     if(c%gcd)return 0;
31     ll t=c/gcd;
32     x*=t;y*=t;
33     if(a*x+b*y!=c)return 0;
34     t=b/gcd;
35     if(t<0)t=-t;
36     while(x<0)x+=t;
37     x%=t;
38     if(!x)x+=t;
39     a/=gcd;b/=gcd;c/=gcd;//4
40     return 1;
41 }
42 inline bool work()
43 {
44     if((!a)&&(!b)&&(!c)){
45         puts("ZenMeZheMeDuo");
46         return 0;
47     }
48     if(a==0&&b==0){
49         puts("0");return 0;
50     }
51     if(!b){
52         if(c*a<0) puts("0");
53         else if(c%a==0) puts("ZenMeZheMeDuo");//5
54         else puts("0");
55         return 0;
56     }
57     if(!a){
58         if(b*c<0) puts("0");
59         else if(c%b==0) puts("ZenMeZheMeDuo");
60         else puts("0");
61         return 0;
62     }
63     if(a*b>0&&(b*c<0||!c)){ puts("0");return 0; }
64     if(a<0&&b<0){a=-a;b=-b;c=-c;}
65     return 1;
66 }
67 int main()
68 {
69     T=read();
70     while(T--){
71         a=read();b=read();c=read();
72         if(!work())continue;//特判
73         ll xi,yi,yj,ans=0;
74         if(!solve(xi,yi)){
75             puts("0");continue;
76         }
77         else{
78             if(a*b<0){//2
79                 puts("ZenMeZheMeDuo");
80                 continue;
81             }
82             if(a+b==c){ puts("1");continue; }
83             if(a==b&&a==1){
84                 c-=1;
85                 if(c>lim) puts("ZenMeZheMeDuo");
86                 else printf("%lld\n",c);
87                 continue;
88             }
89             yi=(c-a*xi)/b;
90             yj=yi%a;
91             if(yj<=0)yj+=a;
92             if(yj>yi){ puts("0");continue; }
93             ans=(yi-yj)/a+1;//3
94             if(ans>lim)puts("ZenMeZheMeDuo");
95             else printf("%lld\n",ans);
96         }
97     }
98     return 0;
99 }
龟速1022ms代码

 

方程的解(exgcd模板)

标签:read   tin   回顾   alt   vector   枚举   rac   img   hid   

原文地址:https://www.cnblogs.com/toot-wjh/p/11235593.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!