SGU 106 The equation

思路:用拓展欧几里得算法可以得出原方程的一个解。然后就可以根据这个解判断在所给的区间里有几个解。
由ax+by+c = 0有ax+by = -c,两边取模b得到
ax+by ≡ -c (mod b) 推出 ax ≡ -c (mod b)
模线性方程有解当且仅当gcd(a,b) | -c,有解的情况下方程对模-c有d个不同的解,d=gcd(a,b)
根据拓展欧几里得算法可以算出x0, y0使得d = a*x0+b*y0
则x =  x0*(-c/d), y = y0*(-c/d)为原方程ax+by+c=0的一个解
则方程的所有解为x = x0*(-c/d) + i*(b/d), y = y0*(-c/d) - i*(a/d)
计算所有的i使得解在所给区间内的个数即可。

代码如下:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<iomanip>
 5 #include<cmath>
 6 #include<cstring>
 7 #include<vector>
 8 #define ll long long int
 9 #define mod 1000000007
10 #define ceils(a,b) ceil(double(a)/double(b)) //向上取整
11 #define floors(a,b) floor(double(a)/double(b))  //向下取整
12 using namespace std;
13 ll extend(ll a,ll b,ll &x,ll &y)
14 {
15     if(b==0){
16         x=1;
17         y=0;
18         return a;
19     }
20     else{
21         ll t=extend(b,a%b,x,y);
22         ll c=x;
23         x=y;
24         y=c-a/b*y;
25         return t;
26     }
27 }
28 int main(){
29     ll a,b,c,x1,x2,y1,y2;
30     ll x,y,k1,k2,k3,k4,d,g;
31     cin>>a>>b>>c>>x1>>x2>>y1>>y2;
32     if(!(x1<=x2&&y1<=y2)) cout<<0<<endl;
33     else if(a==0&&b==0) cout<<(c==0)*(x2-x1+1)*(y2-y1+1)<<endl;
34     else if(a==0){
35         y=-c/b;
36         cout<<((b*y+c==0)&&(y1<=y&&y<=y2))*(x2-x1+1)<<endl;
37     }
38     else if(b==0){
39         x=-c/a;
40         cout<<((a*x+c==0)&&(x1<=x&&x<=x2))*(y2-y1+1)<<endl;
41     }
42     else{
43         g=extend(a,b,x,y);
44         if(c%g==0){
45             a/=g;b/=g;c/=g;
46             x*=-c;y*=-c;
47             if(b>0){
48                 k1=ceils(x1-x,b);
49                 k2=floors(x2-x,b);
50             }
51             else{
52                 k1=ceils(x2-x,b);
53                 k2=floors(x1-x,b);
54             }
55             if(a<0){
56                 k3=ceils(y-y1,a);
57                 k4=floors(y-y2,a);
58             }
59             else{
60                 k3=ceils(y-y2,a);
61                 k4=floors(y-y1,a);
62             }
63             ll mi=min(k2,k4);
64             ll ma=max(k1,k3);
65             if(mi>=ma) cout<<mi-ma+1<<endl;
66             else cout<<0<<endl;
67         }
68         else cout<<0<<endl;
69     }
70     return 0;
71 }
View Code
原文地址:https://www.cnblogs.com/xin-hua/p/3287543.html