方程的解(exgcd模板)

Posted toot-wjh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了方程的解(exgcd模板)相关的知识,希望对你有一定的参考价值。

题面在考试反思中。

题解:

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

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

  我习惯将方程$ ax+by=c $看成一次函数$ y=-\fracabx+\fraccb $

  而在此之前我们要特判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模板)的主要内容,如果未能解决你的问题,请参考以下文章

模拟测试7

[模板] 数学基础:逆元/exGCD/exCRT/Lucas定理/exLucas

[模板] 数学

解线性同余方程组-模板

pOJ-1061 exgcd求同余方程组

同余方程(扩欧模板)