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

 

 

 

你可能感兴趣的:(IO)